微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

delphi – DCPcrypt哈希德国Umlauts

我使用DCPcrypt和SHA512来排列字符串.

我正在使用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库来生成德语变音符的哈希值?谢谢

解决方法

这必须是人们通过散列和加密所造成的最常见的错误.这些algos操作二进制数据,但您正在传递文本.某处某处将该文本编码为二进制.应该使用什么编码.您如何知道您的图书馆与在线工具相同?你没有

所以,这是你遵循的规则.从不哈希文本.只是不要这样做使用明确定义的明确选择的编码将文本编码为二进制.和哈希.我建议你编码为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
  ....

去除不需要的if语句.如果构造函数失败,则会引发异常.

请遵循我的规则永远不要哈希文本.这将为您服务!

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐