我使用DCPcrypt和SHA512来散列字符串。
我使用的版本由沃伦Postma https://bitbucket.org/wpostma/dcpcrypt2010
它工作得很好。但是它在德语变音如ä,ö,ü和可能其他unicode上失败了。
我是这样使用库的:
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;
当我输入字母ä
时,我期望输出为:
2004年12月18日,中国人民银行发布《中国人民银行股份有限公司关于进一步深化改革的通知》,明确了改革的方向。
我查过那些网站:http://hashgenerator.de/http://passwordsgenerator.net/sha512-hash-generator/
然而我得到:
1998年,在美国的一家公司中,有一个名为“美国”的公司。
所以我的问题是:如何使用DCPcrypt库生成德语变音的哈希值?谢谢
1条答案
按热度按时间lf3rwulv1#
这一定是人们在使用哈希和加密时最常犯的错误。这些算法对二进制数据进行操作,但你传递的是文本。某处必须有某种东西将文本编码为二进制。应该使用什么编码。你怎么知道你的图书馆使用的是和在线工具相同的编码?你不知道。
所以,这里有一条规则要遵循。永远不要哈希文本。就是不要这样做。使用一个定义良好的、明确选择的编码将文本编码为二进制。然后哈希它。我建议你编码为UTF-8并哈希它。所以,
TEncoding.UTF8.GetBytes(...)
是你的朋友。现在,查看此处的实际详细信息,您将调用此方法:
参数
RawByteString
意味着你的Unicode文本将被转换成ANSI字符串,使用默认的系统代码页。我敢肯定这不是你想要发生的。实际上编译器是这样说的:[dcc 32警告] W1058从'string'到'RawByteString'的隐含字串转换可能会遗失数据
所以编译器告诉你你做错了什么。你真的必须注意编译器的消息。
现在,您可以调用
UpdateUnicodeStr
而不是UpdateStr
。但是,您又如何知道使用了什么编码呢?它恰好是本机内部编码UTF-16 LE。但是,让我们遵循我的规则,永远不要对文本进行编码。
输出
2004年12月18日,中国人民银行发布《中国人民银行股份有限公司关于进一步深化改革的通知》,明确了改革的方向。
注意,我在其他方面简化了代码。我删除了本地字符串变量,直接使用
Result
。我使用Classes
单元中的BinToHex
将摘要转换为十六进制。我还修改了以下代码:移除不需要的
if
陈述式。如果建构函式失败,就会引发例外状况。请遵守我的规则,永远不要哈希文本。它会为你服务得很好!