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

Delphi中数据库SHA-256二进制字段比对问题求助

问题分析与解决方法

嘿,我之前也踩过一模一样的坑!你遇到的比对失败问题,核心原因是错误地用字符串类型(AsString)去读取二进制字段,这直接破坏了SHA-256哈希的原始字节数据,导致比对完全无效。

为什么会出现乱码+比对失败?

Binary字段存储的是SHA-256的原始字节(32个字节),当你用AsString读取时,系统会把这些字节按当前默认编码(比如ANSI)转换成字符串——但这些字节根本不是合法的文本编码,所以就会出现乱码。而你拼接的'0x' + SHA256(Edit.Text)是哈希的十六进制文本形式,和乱码字符串本质上是两种完全不同的数据,自然永远比对不上。

正确的解决步骤

你猜的没错,必须直接操作二进制数据,而不是转成字符串。虽然你说没找到AsBinary,但Delphi的TField其实提供了AsBytes属性来获取原始字节数组,这就是你需要的工具:

1. 先写一个十六进制字符串转字节数组的工具函数

假设你的SHA256(Edit.Text)返回的是十六进制格式的字符串(比如E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855),需要把它转成和数据库中一致的字节数组:

function HexToBytes(const HexStr: string): TBytes;
var
  I: Integer;
begin
  // 确保十六进制字符串长度是偶数
  if Length(HexStr) mod 2 <> 0 then
    raise Exception.Create('无效的十六进制字符串');
  
  SetLength(Result, Length(HexStr) div 2);
  for I := 0 to Length(Result)-1 do
    Result[I] := StrToInt('$' + Copy(HexStr, I*2+1, 2));
end;

2. 读取数据库二进制哈希并比对

用AsBytes获取数据库中的原始哈希字节,再把用户输入的哈希转成字节数组,最后直接比对两个字节数组的内容:

var
  DBHashBytes: TBytes;
  InputHashBytes: TBytes;
begin
  // 从数据库读取二进制SHA-256哈希
  DBHashBytes := ADOQuery1.FieldByName('pass').AsBytes;
  
  // 将用户输入的SHA-256十六进制字符串转成字节数组
  InputHashBytes := HexToBytes(SHA256(Edit.Text));
  
  // 比对两个字节数组是否完全一致
  if (Length(DBHashBytes) = Length(InputHashBytes)) and 
     CompareMem(@DBHashBytes[0], @InputHashBytes[0], Length(DBHashBytes)) then
  begin
    ShowMessage('密码正确!');
  end
  else
  begin
    ShowMessage('密码错误!');
  end;
end;

特殊情况:如果SHA256函数返回的是字节数组

如果你的SHA256函数直接返回原始字节数组(而不是十六进制字符串),那更简单,直接跳过转码步骤,直接比对:

var
  DBHashBytes: TBytes;
  InputHashBytes: TBytes;
begin
  DBHashBytes := ADOQuery1.FieldByName('pass').AsBytes;
  InputHashBytes := SHA256(Edit.Text); // 假设返回TBytes
  
  if (Length(DBHashBytes) = Length(InputHashBytes)) and 
     CompareMem(@DBHashBytes[0], @InputHashBytes[0], Length(DBHashBytes)) then
    ShowMessage('密码正确!')
  else
    ShowMessage('密码错误!');
end;

额外提醒

  • 永远不要用字符串类型处理二进制数据(比如哈希、加密内容),否则会因编码转换破坏原始数据。
  • 存储哈希时,一定要用Binary/BLOB类型,而不是字符串类型,这样既节省空间,又能避免编码问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 07:00:47