在Delphi中编译为32位或64位时,MD5 base64哈希是不同的 – 我怎样才能使它们相同?

我正在使用Delphi XE2和以下代码创建一个MD5 base64哈希,用于亚马逊MWS.如果我为32位 Windows编译它,它可以工作,但如果我为64位窗口编译,则返回哈希值会发生变化.造成这种情况的原因是什么?我如何更改它以便它们返回相同的哈希值?

function getMd5HashString(value: string): string;
var
  MessageDigest: TIdHashMessageDigest5;
  Content: TBytes;
begin
  Content := TEncoding.UTF8.GetBytes(value);
  MessageDigest:=TIdHashMessageDigest5.Create;
  Result:=Data.Cloud.CloudAPI.EncodeBytes64(MessageDigest.HashBytes(Content));
end;

Thansk提前.

编辑:

我在以下测试中使用上述功能;

procedure Button1Click(Sender: TObject);
begin
  Edit2.Text := getMd5HashString(Edit1.Text);
end;

我过世了

<?xml version="1.0" encoding="utf-8"?>

作为字符串,只是为了测试.如果我使用Windows 32位目标平台编译程序,则返回的哈希是;

I3pK / R hpYOKY1iqrviZbQ ==

然而,如果我使用Windows 64位目标平台编译程序,我会得到;

bmkkAOXGhLdDFCUuNBuSxw ==

我希望大卫回答你?

Edit2:David建议的完整程序;

unit ContentHashTest;

interface

uses
  Winapi.Windows,Winapi.Messages,System.SysUtils,System.Variants,System.Classes,Vcl.Graphics,Vcl.Controls,Vcl.Forms,Vcl.Dialogs,Data.Cloud.CloudAPI,IdGlobal,IdHash,IdHashMessageDigest,IdCoder,IdCoderMIME,Vcl.StdCtrls;

type
  TForm1 = class(TForm)
    Edit1: TEdit;
    Button1: TButton;
    Edit2: TEdit;
    procedure Button1Click(Sender: TObject);
  private
    function getMd5HashString(value: string): string;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
  Edit2.Text := getMd5HashString(Edit1.Text);
end;

function TForm1.getMd5HashString(value: string): string;
var
  MessageDigest: TIdHashMessageDigest5;
  Content: TBytes;
begin
  Content := TEncoding.UTF8.GetBytes(value);
  MessageDigest:=TIdHashMessageDigest5.Create;
  Result:=Data.Cloud.CloudAPI.EncodeBytes64(MessageDigest.HashBytes(Content));
end;

end.

那是我的开始尝试.大卫的建议在下面我把它改成了;

unit ContentHashTest;

interface

uses
  Winapi.Windows,Vcl.StdCtrls;

type
  TForm1 = class(TForm)
    Edit1: TEdit;
    Button1: TButton;
    Edit2: TEdit;
    procedure Button1Click(Sender: TObject);
  private
    function getMd5HashString(value: string): string;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
  Edit2.Text := getMd5HashString(Edit1.Text);
end;

function TForm1.getMd5HashString(value: string): string;
var
  MessageDigest: TIdHashMessageDigest5;
  Content: TIdBytes;
begin
  Content := TIdTextEncoding.UTF8.GetBytes(value);
  MessageDigest := TIdHashMessageDigest5.Create;
  try
    Result := TIdEncoderMIME.EncodeBytes(MessageDigest.HashBytes(Content));
  finally
    MessageDigest.Free;
  end;
end;

end.

不幸的是,结果不同.

Win32 = I3pK / R hpYOKY1iqrviZbQ ==

Win64 = bmkkAOXGhLdDFCUuNBuSxw ==

解决方法

我把问题中的摘录变成了这个完整的程序:

{$APPTYPE CONSOLE}

uses
  SysUtils,IdHashMessageDigest;

function getMd5HashString(value: string): string;
var
  MessageDigest: TIdHashMessageDigest5;
  Content: TIdBytes;
begin
  //Content := TIdTextEncoding.UTF8.GetBytes(value); // for older versions of Indy
  Content := IndyTextEncoding_UTF8.GetBytes(value);
  MessageDigest := TIdHashMessageDigest5.Create;
  try
    Result := TIdEncoderMIME.EncodeBytes(MessageDigest.HashBytes(Content));
  finally
    MessageDigest.Free;
  end;
end;

begin
  Writeln(getMd5HashString('<?xml version="1.0" encoding="utf-8"?>'));
  Readln;
end.

我正在使用Indy来执行所有转换:文本为UTF-8字节,MD5散列和base64编码.但是你应该使用任何库,因为它们都应该提供相同的输出.

该程序产生32位和64位的相同输出,如预期的那样:

I3pK/R+hpYOKY1iqrviZbQ==

你报告了不同的行为,那么原因可能是什么?我可以想到以下可能的解释:

>实际上,您并没有在两个版本中将相同的输入值传递给函数.
> TEncoding.UTF8.GetBytes有缺陷.
> TIdHashMessageDigest5.HashBytes有缺陷.
> Data.Cloud.CloudAPI.EncodeBytes64有缺陷.

无论如何,我认为使用Data.Cloud.CloudAPI执行base64编码没有任何意义,尽管我没有理由相信它不起作用.由于您已经在使用Indy库,因此统一执行此操作更有意义.

我无法从这里看出上述哪些解释是您报告的原因.您应该能够进一步调试以找出答案.查看流程中每个步骤的输出,以确定行为的变化位置.

更新:我现在已经设法重现错误,但只能使用XE2附带的Indy版本.我在最初的实验中使用了更新版本的Indy.

问题似乎是我的列表中的第3项.这在x64编译器下给出了错误的结果.

您应该通过查找不同的MD5实现来解决问题.我的建议是通过升级Indy来做到这一点.

相关文章

 从网上看到《Delphi API HOOK完全说明》这篇文章,基本上都...
  从网上看到《Delphi API HOOK完全说明》这篇文章,基本上...
ffmpeg 是一套强大的开源的多媒体库 一般都是用 c/c+&#x...
32位CPU所含有的寄存器有:4个数据寄存器(EAX、EBX、ECX和ED...
1 mov dst, src dst是目的操作数,src是源操作数,指令实现的...