将 C# 函数转换为 Delphi 函数
Convert C# function to Delphi function
我需要将此 C# 函数转换为 Delphi。我正在转换一个函数,它将根据 CPU id、BIOS id 和主板 id 生成一个字符串。
有人能帮帮我吗?
private string GetHash(string s)
{
return ComputerInfo.GetHexString(new MD5CryptoServiceProvider().ComputeHash(new ASCIIEncoding().GetBytes(s)));
}
private string GetHexString(byte[] bt)
{
string str1 = string.Empty;
int myLenght = bt.Length - 8;
for (int index = 0; index < myLenght; ++index)
{
int num1 = (int)bt[index];
int num2 = num1 & 15;
int num3 = num1 >> 4 & 15;
string str2 = num3 <= 9 ? str1 + num3.ToString() : str1 + ((char)(num3 - 10 + 65)).ToString();
str1 = num2 <= 9 ? str2 + num2.ToString() : str2 + ((char)(num2 - 10 + 65)).ToString();
if (index + 1 != myLenght && (index + 1) % 2 == 0)
str1 += "-";
}
return str1;
}
我尝试了几种方法来转换函数,但我仍然无法获得与原始函数相同的值。在我的笔记本电脑上,我得到字符串 '1CB9-0485-D2FD-846C'
但在 Delphi 中,我得到字符串 '3237-3939-3232-4433-4141-3835-4342-4536-4145-3344-3933-383736'
.
function TAppForm.GetHexString(bt : TBytes) : string;
var
str1: string;
str2: string;
myLength: Integer;
index: Integer;
num1: Integer;
num2: Integer;
num3: Integer;
begin
str1 := string.Empty;
myLength := Length(bt) - 8;
for index := 0 to myLength do
begin
num1 := Integer(bt[index]);
num2 := num1 and 15;
num3 := num1 shr 4 and 15;
If num3 <= 9 then
str2 := str1 + num3.ToString()
else
str2 := str1 + Chr(num3 - 10 + 65);
If num2 <= 9 then
str1 := str2 + num2.ToString()
else
str1 := str2 + Chr(num2 - 10 + 65);
if ((index + 1) <> myLength) and ((index + 1) mod 2 = 0) then
str1 := str1 + '-';
end;
Result := str1;
end;
function TAppForm.MyGetMD5(Value : String) : String;
var
workHash : TIdHashMessageDigest5;
begin
workHash := TIdHashMessageDigest5.Create;
try
Result := workHash.HashStringAsHex(Value);
finally
FreeAndNil(workHash);
end;
end;
function TAppForm.GetHash(s : string) : string;
var
//bytes: TBytes;
bytes: TBytes;
smd5: string;
begin
smd5 := MyGetMD5(s);
bytes := TEncoding.ASCII.GetBytes(smd5);
smd5 := GetHexString(bytes);
Result := smd5;
end;
非常感谢@olivier 的解决方案。其实和我想要的很接近
然而,我在 C# 中得到的结果是 "1CB9-0485-D2FD-846C"
,而使用你的解决方案我得到 "0126-28BE-D776-1788"
。
我试图理解为什么,因为请求哈希的字符串是相同的。
在C#中,请求如下
GetHash("CPU >>" + ComputerInfo.CpuId() + "\nBIOS >>" + ComputerInfo.BiosId() + "\nBASE >>" + ComputerInfo.BaseId());
结果
CPU BFEBFBFF000306D4
BIOS INSYDE Corp.5.308F014604C20160325000000.000000 + 000TOSQCI - 1
BASE FF50Base BoardQC0C0Q8F3000710
在Delphi中,请求如下
const
sLineBreak = {$IFDEF LINUX} AnsiChar (#10) {$ENDIF}
{$IFDEF MSWINDOWS} AnsiString (#13#10) {$ENDIF};
GetHash('CPU >>' + CpuId() + sLineBreak + 'BIOS >>' + BiosId() + sLineBreak + 'BASE >>' + BaseId());
结果
CPU BFEBFBFF000306D4
BIOS INSYDE Corp.5.308F014604C20160325000000.000000 + 000TOSQCI - 1
BASE FF50Base BoardQC0C0Q8F3000710
这是一个有效的实现。它使用 THashMD5
,在 Delphi.
的最新版本中可用。
uses
System.Hash;
function GetHexString(const b: TBytes): string;
var
len: Integer;
index: Integer;
num1: Byte;
num2: Byte;
num3: Byte;
begin
Result := '';
len := Length(b) - 8;
for index := 0 to len - 1 do
begin
num1 := b[index];
num2 := num1 and 15;
num3 := (num1 shr 4) and 15;
If num3 <= 9 then
Result := Result + num3.ToString()
else
Result := Result + Chr(num3 - 10 + 65);
If num2 <= 9 then
Result := Result + num2.ToString()
else
Result := Result + Chr(num2 - 10 + 65);
if ((index + 1) <> len) and ((index + 1) mod 2 = 0) then
Result := Result + '-';
end;
end;
function GetHash(const s: string): string;
var
b, hash: TBytes;
md5: THashMD5;
begin
b := TEncoding.ASCII.GetBytes(s);
md5 := THashMD5.Create;
md5.update(b);
hash := md5.HashAsBytes;
Result := GetHexString(hash);
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
ShowMessage(GetHash('Test'));
end;
C# 和 Delphi 实现输出 0CBC-6611-F554-0BD0
输入字符串 Test
。
Delphi 逻辑与 C# 逻辑不匹配。
C# 代码正在执行以下操作:
- 将 Unicode 字符串转换为 ASCII 字节数组
- 然后对这些字节进行 MD5 哈希处理
- 然后将该散列的字节编码为格式化的十六进制字符串
Delphi 代码执行以下操作:
- (隐式)将 Unicode 字符串转换为 ASCII 字节数组
- 然后对这些字节进行 MD5 哈希处理
- 然后将该散列的字节编码为普通的十六进制字符串
- 然后将该十六进制字符串转换为 ASCII 字节数组
- 然后将这些字节编码为格式化的十六进制字符串
因此,您当然会得到不同的结果,因为最终的十六进制字符串是根据完全不同的输入进行编码的。
正确的翻译应该看起来更像这样:
function TAppForm.GetHash(const s: string): string;
var
workHash : TIdHashMessageDigest5;
begin
workHash := TIdHashMessageDigest5.Create;
try
Result := GetHexString(workHash.HashString(s, IndyTextEncoding_ASCII));
finally
workHash.Free;
end;
end;
function TAppForm.GetHexString(bt: TIdBytes): string;
var
str1, str2: string;
myLenght,
index,
num1, num2, num3: Integer;
begin
str1 := '';
myLenght := Length(bt) - 8;
for index := 0 to myLenght-1 do
begin
num1 := Integer(bt[index]);
num2 := num1 and 15;
num3 := (num1 shr 4) and 15;
if num3 <= 9 then
str2 := str1 + IntToStr(num3)
else
str2 := str1 + Char(num3 - 10 + 65);
if num2 <= 9 then
str1 := str2 + IntToStr(num2)
else
str1 := str2 + Char(num2 - 10 + 65);
if ((index + 1) <> myLenght) and ((index + 1) mod 2 = 0) then
str1 := str1 + '-';
end;
Result := str1;
end;
此外,C# 中的 '\n'
字符只是一个换行符。它与 Windows 上 Delphi 中的 #13#10
(回车 return + 换行)字符序列不同。因此,您对 GetHash()
的输入在 C# 和 Delphi 之间也不相同。你根本不应该使用 sLineBreak
常数,只使用 #10
本身,例如:
GetHash('CPU >>' + CpuId() + #10'BIOS >>' + BiosId() + #10'BASE >>' + BaseId());
我需要将此 C# 函数转换为 Delphi。我正在转换一个函数,它将根据 CPU id、BIOS id 和主板 id 生成一个字符串。
有人能帮帮我吗?
private string GetHash(string s)
{
return ComputerInfo.GetHexString(new MD5CryptoServiceProvider().ComputeHash(new ASCIIEncoding().GetBytes(s)));
}
private string GetHexString(byte[] bt)
{
string str1 = string.Empty;
int myLenght = bt.Length - 8;
for (int index = 0; index < myLenght; ++index)
{
int num1 = (int)bt[index];
int num2 = num1 & 15;
int num3 = num1 >> 4 & 15;
string str2 = num3 <= 9 ? str1 + num3.ToString() : str1 + ((char)(num3 - 10 + 65)).ToString();
str1 = num2 <= 9 ? str2 + num2.ToString() : str2 + ((char)(num2 - 10 + 65)).ToString();
if (index + 1 != myLenght && (index + 1) % 2 == 0)
str1 += "-";
}
return str1;
}
我尝试了几种方法来转换函数,但我仍然无法获得与原始函数相同的值。在我的笔记本电脑上,我得到字符串 '1CB9-0485-D2FD-846C'
但在 Delphi 中,我得到字符串 '3237-3939-3232-4433-4141-3835-4342-4536-4145-3344-3933-383736'
.
function TAppForm.GetHexString(bt : TBytes) : string;
var
str1: string;
str2: string;
myLength: Integer;
index: Integer;
num1: Integer;
num2: Integer;
num3: Integer;
begin
str1 := string.Empty;
myLength := Length(bt) - 8;
for index := 0 to myLength do
begin
num1 := Integer(bt[index]);
num2 := num1 and 15;
num3 := num1 shr 4 and 15;
If num3 <= 9 then
str2 := str1 + num3.ToString()
else
str2 := str1 + Chr(num3 - 10 + 65);
If num2 <= 9 then
str1 := str2 + num2.ToString()
else
str1 := str2 + Chr(num2 - 10 + 65);
if ((index + 1) <> myLength) and ((index + 1) mod 2 = 0) then
str1 := str1 + '-';
end;
Result := str1;
end;
function TAppForm.MyGetMD5(Value : String) : String;
var
workHash : TIdHashMessageDigest5;
begin
workHash := TIdHashMessageDigest5.Create;
try
Result := workHash.HashStringAsHex(Value);
finally
FreeAndNil(workHash);
end;
end;
function TAppForm.GetHash(s : string) : string;
var
//bytes: TBytes;
bytes: TBytes;
smd5: string;
begin
smd5 := MyGetMD5(s);
bytes := TEncoding.ASCII.GetBytes(smd5);
smd5 := GetHexString(bytes);
Result := smd5;
end;
非常感谢@olivier 的解决方案。其实和我想要的很接近
然而,我在 C# 中得到的结果是 "1CB9-0485-D2FD-846C"
,而使用你的解决方案我得到 "0126-28BE-D776-1788"
。
我试图理解为什么,因为请求哈希的字符串是相同的。
在C#中,请求如下
GetHash("CPU >>" + ComputerInfo.CpuId() + "\nBIOS >>" + ComputerInfo.BiosId() + "\nBASE >>" + ComputerInfo.BaseId());
结果
CPU BFEBFBFF000306D4 BIOS INSYDE Corp.5.308F014604C20160325000000.000000 + 000TOSQCI - 1 BASE FF50Base BoardQC0C0Q8F3000710
在Delphi中,请求如下
const
sLineBreak = {$IFDEF LINUX} AnsiChar (#10) {$ENDIF}
{$IFDEF MSWINDOWS} AnsiString (#13#10) {$ENDIF};
GetHash('CPU >>' + CpuId() + sLineBreak + 'BIOS >>' + BiosId() + sLineBreak + 'BASE >>' + BaseId());
结果
CPU BFEBFBFF000306D4 BIOS INSYDE Corp.5.308F014604C20160325000000.000000 + 000TOSQCI - 1 BASE FF50Base BoardQC0C0Q8F3000710
这是一个有效的实现。它使用 THashMD5
,在 Delphi.
uses
System.Hash;
function GetHexString(const b: TBytes): string;
var
len: Integer;
index: Integer;
num1: Byte;
num2: Byte;
num3: Byte;
begin
Result := '';
len := Length(b) - 8;
for index := 0 to len - 1 do
begin
num1 := b[index];
num2 := num1 and 15;
num3 := (num1 shr 4) and 15;
If num3 <= 9 then
Result := Result + num3.ToString()
else
Result := Result + Chr(num3 - 10 + 65);
If num2 <= 9 then
Result := Result + num2.ToString()
else
Result := Result + Chr(num2 - 10 + 65);
if ((index + 1) <> len) and ((index + 1) mod 2 = 0) then
Result := Result + '-';
end;
end;
function GetHash(const s: string): string;
var
b, hash: TBytes;
md5: THashMD5;
begin
b := TEncoding.ASCII.GetBytes(s);
md5 := THashMD5.Create;
md5.update(b);
hash := md5.HashAsBytes;
Result := GetHexString(hash);
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
ShowMessage(GetHash('Test'));
end;
C# 和 Delphi 实现输出 0CBC-6611-F554-0BD0
输入字符串 Test
。
Delphi 逻辑与 C# 逻辑不匹配。
C# 代码正在执行以下操作:
- 将 Unicode 字符串转换为 ASCII 字节数组
- 然后对这些字节进行 MD5 哈希处理
- 然后将该散列的字节编码为格式化的十六进制字符串
Delphi 代码执行以下操作:
- (隐式)将 Unicode 字符串转换为 ASCII 字节数组
- 然后对这些字节进行 MD5 哈希处理
- 然后将该散列的字节编码为普通的十六进制字符串
- 然后将该十六进制字符串转换为 ASCII 字节数组
- 然后将这些字节编码为格式化的十六进制字符串
因此,您当然会得到不同的结果,因为最终的十六进制字符串是根据完全不同的输入进行编码的。
正确的翻译应该看起来更像这样:
function TAppForm.GetHash(const s: string): string;
var
workHash : TIdHashMessageDigest5;
begin
workHash := TIdHashMessageDigest5.Create;
try
Result := GetHexString(workHash.HashString(s, IndyTextEncoding_ASCII));
finally
workHash.Free;
end;
end;
function TAppForm.GetHexString(bt: TIdBytes): string;
var
str1, str2: string;
myLenght,
index,
num1, num2, num3: Integer;
begin
str1 := '';
myLenght := Length(bt) - 8;
for index := 0 to myLenght-1 do
begin
num1 := Integer(bt[index]);
num2 := num1 and 15;
num3 := (num1 shr 4) and 15;
if num3 <= 9 then
str2 := str1 + IntToStr(num3)
else
str2 := str1 + Char(num3 - 10 + 65);
if num2 <= 9 then
str1 := str2 + IntToStr(num2)
else
str1 := str2 + Char(num2 - 10 + 65);
if ((index + 1) <> myLenght) and ((index + 1) mod 2 = 0) then
str1 := str1 + '-';
end;
Result := str1;
end;
此外,C# 中的 '\n'
字符只是一个换行符。它与 Windows 上 Delphi 中的 #13#10
(回车 return + 换行)字符序列不同。因此,您对 GetHash()
的输入在 C# 和 Delphi 之间也不相同。你根本不应该使用 sLineBreak
常数,只使用 #10
本身,例如:
GetHash('CPU >>' + CpuId() + #10'BIOS >>' + BiosId() + #10'BASE >>' + BaseId());