在 C# 中,我们有这个函数:
public string GetStringSha256Hash(string text, Encoding coding)
{
string result = "";
if (text != null)
{
using (SHA256 sHA256Managed = SHA256.Create())
{
byte[] bytes = coding.GetBytes(text);
byte[] array = sHA256Managed.ComputeHash(bytes);
result = BitConverter.ToString(array).Replace("-", string.Empty);
}
}
return result;
}
我尝试在 Delphi 中执行相同操作,但得到的结果却不同。
就像这样简单的事情:
Result := THashSHA2.GetHashString(Text);
返回不同的结果。
我怀疑是因为在 C# 中我们总是使用 UTF-8,但我找不到如何在 Delphi 中使用编码。
我尝试过这个:
var
Hash: TIdHashSHA256;
begin
Hash := TIdHashSHA256.Create;
try
SHA256Hash := Hash.HashString(Text, TEncoding.UTF8);
但它给出了一个编译错误
[dcc32 错误] Unit1.pas(216): E2010 不兼容类型:“IIdTextEncoding”和“TEncoding”
在 Delphi 中执行此操作的正确方法是什么?
该值在 C# 中12345
返回,但在 Delphi 中却返回。1445217533E7D4D0CFFD9109C4EDB60D62A02C0F0DE9537BE44F5E00D348EB4F
5994471abb01112afcc18159f6cc74b4f511b99806da59b3caf5a9c173cacfc5
我希望 Delphi 版本返回与 C# 版本相同的值。
哈希值是根据字节而不是文本字符计算的。任何用于哈希字符串的代码都需要先将字符编码为字节,然后再计算字节的哈希值。当在不同系统之间对字符串进行哈希处理时,您需要确保它们使用相同的字节编码。
C# 代码通过 将输入编码
string
为字节数组coding.GetBytes(text)
。您没有指出Encoding
将哪个传递给GetStringSha256Hash()
,但您显示的 C# 哈希结果是使用 UTF-16LE (即 ) 对字符串进行哈希处理时获得的结果Encoding.Unicode
。使用 Delphi RTL 的
THashSHA2
类时,它不允许您在散列 时指定字节编码string
。GetHashString()
接受 的方法string
被硬编码为使用TEncoding.UTF8
。这与您显示的 Delphi 散列结果一致。要使用不同的字节编码,备选方案如下:使用
THashSHA2.GetHashString()
接受的重载TStream
,然后您可以传入包含 UTF-16LE 编码字节的流,例如:使用该
THashSHA2.Update()
方法,向其传递一个 UTF-16 编码的字节数组,例如:当使用 Indy 的
TIdHashSHA256
类时,编译器错误是由于 Indy 没有使用 Delphi RTL 的TEncoding
类1,而是使用了它自己的IIdTextEncoding
接口(因为 Indy 仍然支持没有可用SysUtils.TEncoding
类的 Delphi 的 Unicode 之前的版本),例如:1:如果您想与 Indy 一起使用
SysUtils.TEncoding
,您可以将其包装到IIdTextEncoding
使用单元IndyTextEncoding()
中的函数中IdGlobal
,例如: