2016-03-03 7 views
11

DCPcryptとSHA512を使用して文字列をハッシュします。それが正常に動作しているhttps://bitbucket.org/wpostma/dcpcrypt2010DCPcryptドイツ語Umlautsをハッシュする

私はウォーレンポストマでバージョンを使用しています。しかし、それはä、ö、ü、おそらく他のユニコードのようなドイツ語のウムラウトでは失敗します。

私はこのようなライブラリを使用しています:

64868C5784A6004E675BCF405F549369BF607CD3269C0CAC1711E21BA9F40A5ABBF0C7535856E7CF77EA55A072DD04AA89EEA361E95F497AA965309B50587157

が、私はそれらとそれを確認:

function TForm1.genhash(str: string): string; 
var 
    Hash : TDCP_sha512; 
    Digest: array[0..63] of byte; 
    i: integer; 
    s: string; 
begin 
    s:= ''; 
    hash := TDCP_sha512.Create(nil); 
    if hash<>nil then 
    begin 
    try 
     Hash.Init; 
     Hash.UpdateStr(str); 
     Hash.Final(Digest); 

     for i:= 0 to length(Digest)-1 do 
     s:= s + IntToHex(Digest[i],2); 

    finally 
     hash.free; 
    end; 

    end; 
    Result := s; 
end; 

私は入力文字ä iは出力があることを期待

サイト: http://hashgenerator.de/ http://passwordsgenerator.net/sha512-hash-generator/

は、しかし、私は得る:

1A7F725BD18E062020A646D4639F264891368863160A74DF2BFC069C4DADE04E6FA854A2474166EED0914B922A9D8BE0C89858D437DDD7FBCA5C9C89FC07323A

だから私の質問は次のとおりです。 はどのように私はドイツ語のウムラウトのためのハッシュを生成するDCPcryptライブラリを使用することができますか? THanks

答えて

18

これは、人々がハッシュと暗号化を使用して行う最も一般的な間違いでなければなりません。これらのアルゴスはバイナリデータで動作しますが、テキストを渡しています。どこかでバイナリとしてそのテキストをエンコードしなければなりません。そして、どんなエンコーディングが使われるべきですか?あなたのライブラリがオンラインツールと同じものを使用していることをどのように知っていますか?あなたはそうしない。

ここでは、あなたが従うべきルールがあります。テキストをハッシュしないでください。ただしないでください。明確かつ明確に選択されたエンコーディングを使用してテキストをバイナリとしてエンコードします。そしてそれをハッシュしてください。 UTF-8でエンコードしてハッシュすることをお勧めします。だから、TEncoding.UTF8.GetBytes(...)はここにあなたの友人です。

は今、ここでは実際の詳細を見て、あなたは、このメソッドを呼び出している:

procedure UpdateStr(const Str: RawByteString); 

RawByteStringパラメータは、お使いのUnicodeテキストは、デフォルトのシステムコードページで、ANSI文字列に変換されていることを意味します。私はそれがあなたが起こそうとしているものではないと確信しています。だから、コンパイラはあなたが何か間違ったことをやっていることを語っている「RawByteString」

[DCC32の警告]「文字列」からの潜在的なデータ損失のW1058暗黙の文字列キャスト:確かに、コンパイラはこれを言います。あなたは本当にコンパイラのメッセージに注意を払う必要があります。

UpdateStrの代わりにUpdateUnicodeStrに電話することができます。しかし、もう一度、エンコーディングがどのように使われているかをどのように知っていますUTF-16LEの内部エンコーディングです。

しかし、テキストをエンコードしないという私のルールに従ってみましょう。私はいくつかの他の方法でコードを単純化し

{$APPTYPE CONSOLE} 

uses 
    SysUtils, Classes, DCPsha512; 

function genhash(str: string): string; 
var 
    Bytes: TBytes; 
    Hash: TDCP_sha512; 
    Digest: array[0..63] of byte; 
begin 
    Bytes := TEncoding.UTF8.GetBytes(str); // encode text as UTF-8 bytes 

    hash := TDCP_sha512.Create(nil); 
    try 
    Hash.Init; 
    Hash.Update(Pointer(Bytes)^, Length(Bytes)); 
    Hash.Final(Digest); 
    finally 
    hash.Free; 
    end; 

    // convert the digest to a hex hash string 
    SetLength(Result, Length(Digest)*2); 
    BinToHex(Digest, PChar(Result), Length(Digest)); 
end; 

begin 
    Writeln(genhash('ä')); 
    Readln; 
end. 

出力

64868C5784A6004E675BCF405F549369BF607CD3269C0CAC1711E21BA9F40A5ABBF0C7535856E7CF77EA55A072DD04AA89EEA361E95F497AA965309B50587157

注意。私はローカルの文字列変数を削除し、Resultで直接作業しました。私はClassesユニットのBinToHexを使って、ダイジェストから16進への変換を行いました。私もこのコードを変更しました:

hash := TDCP_sha512.Create(nil); 
if hash<>nil then 
    .... 

ifステートメントは不要です。コンストラクタが失敗すると、例外が発生します。

テキストをハッシュしないように私のルールに従ってください。それはあなたによく役立つでしょう!

+1

Davidにこの素晴らしい答えをありがとう。説明を感謝し、間違いなく何かを学んだ! – Tommy

+2

素晴らしい。そして、あなたの質問に感謝します。問題の明確な声明を出して、しばらくの間私のところにたどりついていたことを最終的に書き留める機会があります。私はこのQ&Aを使ってバイナリやテキストをハッシュと暗号で広めることができることを願っています! –

関連する問題