我正在使用Warren Postma https://bitbucket.org/wpostma/dcpcrypt2010的版本
工作正常然而,它与德国的变音乐像ä,ö,ü以及其他unicodes一样失败.
我正在使用图书馆:
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;
当我输入字母ä我希望输出为:
64868C5784A6004E675BCF405F549369BF607CD3269C0CAC1711E21BA9F40A5ABBF0C7535856E7CF77EA55A072DD04AA89EEA361E95F497AA965309B50587157
我检查了这些网站:
http://hashgenerator.de/
http://passwordsgenerator.net/sha512-hash-generator/
但是我得到:
1A7F725BD18E062020A646D4639F264891368863160A74DF2BFC069C4DADE04E6FA854A2474166EED0914B922A9D8BE0C89858D437DDD7FBCA5C9C89FC07323A
所以我的问题是:
我如何使用DCPcrypt库来生成德语变音符的哈希值?谢谢
解决方法
所以,这是你遵循的规则.从不哈希文本.只是不要这样做使用明确定义的明确选择的编码将文本编码为二进制.和哈希.我建议你编码为UTF-8和哈希.所以,TEncoding.UTF8.GetBytes(…)是你的朋友.
现在看这里的实际细节,你叫这个方法:
procedure UpdateStr(const Str: RawByteString);
RawByteString参数,表示您的Unicode文本正在转换为ANSI字符串,并带有默认的系统代码页.我相信这不是你打算发生的事情.实际上,编译器说:
[dcc32 Warning] W1058 Implicit string cast with potential data loss from ‘string’ to ‘RawByteString’
所以编译器告诉你你做错了什么你真的必须注意编译器的消息.
现在,您可以调用UpdateUnicodeStr而不是UpdateStr.但是,再一次,你怎么知道使用什么编码?它恰好是本地内部编码,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来进行十六进制转换的摘要.我也改了这个代码:
hash := TDCP_sha512.Create(nil); if hash<>nil then ....
请遵循我的规则永远不要哈希文本.这将为您服务!