You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Delphi Alexandria中Lockbox3计算MD5触发Integer overflow异常求助

Delphi Alexandria环境下Lockbox3 MD5哈希代码触发Integer overflow异常

我使用Lockbox3已有多年,此前在Delphi XE7环境下使用(版本约为3.4,源码中未找到版本号)。现在迁移至Delphi Alexandria,采用Getit包管理器提供的Lockbox3版本,执行代码时在MyHash.HashAnsiString(src);处触发了Integer overflow异常。

我的代码如下:

function TForm1.md5(src: string): string;
  function Display(Buf: TBytes): String;
  var i: Integer;
  begin
    Result := '';
    for i := 0 to 15 do
      Result := Result + Format('%0.2x', [Buf[i]]);
    Result := LowerCase(Trim(Result));
  end;
var
  output : AnsiString;
  bytes : TBytes;
  P, Sz: integer;
  aByte: byte;
  s: string;
  MyHash : THash;
  Lib : TCryptographicLibrary;
begin
  Lib := TCryptographicLibrary.Create(nil);
  MyHash := THash.Create(nil);
  MyHash.CryptoLibrary := Lib;
  MyHash.HashId := 'native.hash.MD5';
  MyHash.Begin_Hash;
  MyHash.HashAnsiString(src);
  if not assigned(MyHash.HashOutputValue) then
    output := 'nil'
  else
  begin
    SetLength(Bytes, 16);
    Sz := MyHash.HashOutputValue.Size;
    if Sz <> 16 then
      output := Format('wrong size: %d', [Sz])
    else
    begin
      P := 0;
      MyHash.HashOutputValue.Position := 0;
      while MyHash.HashOutputValue.Read(aByte, 1) = 1 do
      begin
        bytes[P] := aByte;
        Inc(P);
      end;
      result := Display(Bytes);
    end;
  end;
  MyHash.Destroy;
  Lib.Destroy;
end;

问题原因与解决方法

1. 核心原因

Delphi Alexandria默认字符串为UnicodeString,而HashAnsiString方法接收AnsiString参数。隐式类型转换时,新版本Lockbox3的内部长度处理逻辑发生变化,导致整数溢出。此外旧代码缺少显式的哈希收尾调用,也可能引发资源或计算状态异常。

2. 修复方案

替换哈希方法并补全流程

  • 用HashString替代HashAnsiString:该方法专门适配Unicode字符串,无需类型转换
  • 显式调用End_Hash:新版本Lockbox3需要手动结束哈希计算,确保输出值正确生成
  • 简化结果读取:直接使用HashOutputValue.AsBytes获取字节数组,避免手动流读取的冗余代码

修改后的完整函数:

function TForm1.md5(src: string): string;
  function Display(Buf: TBytes): String;
  var i: Integer;
  begin
    Result := '';
    for i := 0 to High(Buf) do
      Result := Result + Format('%0.2x', [Buf[i]]);
    Result := LowerCase(Trim(Result));
  end;
var
  MyHash : THash;
  Lib : TCryptographicLibrary;
  HashBytes: TBytes;
begin
  Lib := TCryptographicLibrary.Create(nil);
  try
    MyHash := THash.Create(nil);
    try
      MyHash.CryptoLibrary := Lib;
      MyHash.HashId := 'native.hash.MD5';
      MyHash.Begin_Hash;
      MyHash.HashString(src); // 适配Unicode字符串的哈希方法
      MyHash.End_Hash; // 显式结束哈希计算
      HashBytes := MyHash.HashOutputValue.AsBytes;
      if Length(HashBytes) = 16 then
        Result := Display(HashBytes)
      else
        Result := Format('wrong size: %d', [Length(HashBytes)]);
    finally
      MyHash.Free; // 用Free替代Destroy,更符合Delphi资源管理规范
    end;
  finally
    Lib.Free;
  end;
end;

额外优化点

  • 使用try...finally块管理资源:避免代码异常时出现内存泄漏,比直接调用Destroy更安全
  • 遍历字节数组改用High(Buf):避免硬编码16位长度,适配其他哈希算法的结果长度

内容的提问来源于stack exchange,提问作者MSSI

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 10:24:14