DCPcrypt Hashing德国变形金刚

Tom*_*mmy 11 delphi delphi-10-seattle

我使用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;
Run Code Online (Sandbox Code Playgroud)

当我输入字母时,ä我希望输出为:

64868C5784A6004E675BCF405F549369BF607CD3269C0CAC1711E21BA9F40A5ABBF0C7535856E7CF77EA55A072DD04AA89EEA361E95F497AA965309B50587157

我查看了这些网站:http : //hashgenerator.de/ http://passwordsgenerator.net/sha512-hash-generator/

但是我得到:

1A7F725BD18E062020A646D4639F264891368863160A74DF2BFC069C4DADE04E6FA854A2474166EED0914B922A9D8BE0C89858D437DDD7FBCA5C9C89FC07323A

所以我的问题是:我如何使用DCPcrypt库为德语变音符号生成哈希?谢谢

Dav*_*nan 19

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

所以,这是你遵循的规则.永远不要散文.只是不要这样做.使用明确定义的明确选择的编码将文本编码为二进制文件.哈希那个.我建议你编码为UTF-8并哈希.那么,TEncoding.UTF8.GetBytes(...)你的朋友在这里吗?

现在,查看此处的实际细节,您将调用此方法:

procedure UpdateStr(const Str: RawByteString);
Run Code Online (Sandbox Code Playgroud)

RawByteString参数表示您的Unicode文本正在转换为ANSI字符串,并带有默认的系统代码页.我敢肯定,这不是你打算发生的事情.确实编译器这样说:

[dcc32警告] W1058隐含字符串转换,潜在数据从'string'丢失到'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.
Run Code Online (Sandbox Code Playgroud)

产量

64868C5784A6004E675BCF405F549369BF607CD3269C0CAC1711E21BA9F40A5ABBF0C7535856E7CF77EA55A072DD04AA89EEA361E95F497AA965309B50587157

请注意,我以其他方式简化了代码.我删除了本地字符串变量并直接使用Result.我BinToHexClasses单位用来做摘要转换为十六进制.我也更改了这段代码:

hash := TDCP_sha512.Create(nil);
if hash<>nil then
  ....
Run Code Online (Sandbox Code Playgroud)

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

请遵循我的规则永远不要哈希文本.它会为你服务!

  • 大.谢谢你的提问.很高兴能够清楚地了解问题,并有机会最终写下一段时间以来一直困扰着我的事情.我希望我们可以使用此问答来通过散列和加密来传播关于二进制和文本的信息! (2认同)