将 MD5 存储在 MySQL 中
Storing MD5 in MySQL
我不想将 MD5 hash
存储在 32 字节的字段中,而是将其存储在 16 字节的二进制字段中。 Mysql 字段“TEMP_MD5”定义为 Binary(16)。
带有示例行插入的 MySQL CREATE TABLE 是:
CREATE TABLE `mytable` (
`TEMP_MD5` binary(16) DEFAULT NULL,
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO mytable (TEMP_MD5) VALUES UNHEX("202cb962ac59075b964b07152d234b70") );
示例代码:
假设在MySQL字段中存储了16字节的二进制字段TEMP_MD5,我检索后如何在Delphi代码中比较这个16字节的字段值?
是否可以跳过MySQLHEX/UNHEX内部函数,直接用Delphi代码比较[=44中的16字节二进制字段(32字节字符串) =]?
例如:
FDQuery1.Open( 'SELECT TEMP_MD5 from mytable;' );
if THashMD5.GetHashBytes('123') = fDQuery1.FieldByName('TEMP_MD5').VALUE then
SHOWMESSAGE('MATCHED!');
但是,FieldByName('TEMP_MD5').value 的值似乎与 THashMD5.GetHashString('123') 的值
不匹配
另一种使用SELECT语句进行比较的方法也失败了
FDQuery1.Open( 'SELECT TEMP_MD5 mytable ' +
'WHERE (TEMP_MD5=:myvalue)',
[THashMD5.GetHashBytes('123')] );
以上也未能给出FDQuery1.RecordCount = 1
.
基本上我试图将我存储在 MySQL 中的 16 字节二进制文件与一个值进行比较,假设代码中的“123”是否匹配。
我正在使用 Delphi 10.2,明年将升级到 10.4。
下面是一个代码示例,展示了如何将 MD5 写入数据库以及如何读回它并与给定的 MD5 哈希进行比较:
正在插入数据:
procedure TForm1.InsertDataButtonClick(Sender: TObject);
var
MD5 : TArray<Byte>;
begin
MD5 := THashMD5.GetHashBytes('123');
FDConnection1.Connected := TRUE;
FDQuery1.SQL.Text := 'INSERT INTO mytable (TEMP_MD5) VALUES(:MD5)';
FDQuery1.ParamByName('MD5').SetBlobRawData(Length(MD5), PByte(MD5));
FDQuery1.ExecSQL;
Memo1.Lines.Add('Rows affected = ' + FDQuery1.RowsAffected.ToString);
end;
正在读回数据并与给定的哈希值进行比较:
procedure TForm1.ReadDataButtonClick(Sender: TObject);
var
MD5 : TArray<Byte>;
MD5_123 : TArray<Byte>;
FieldMD5 : TField;
RecCnt : Integer;
begin
MD5_123 := THashMD5.GetHashBytes('123');
FDConnection1.Connected := TRUE;
// First version: get all records
// FDQuery1.SQL.Text := 'SELECT TEMP_MD5 FROM mytable';
// Second version: Get only records where TEMP_MD5 is hash('123').
FDQuery1.SQL.Text := 'SELECT TEMP_MD5 FROM mytable WHERE TEMP_MD5 = :MD5';
FDQuery1.ParamByName('MD5').SetBlobRawData(Length(MD5_123), PByte(MD5_123));
// Execute the query
FDQuery1.Open;
RecCnt := 0;
while not FDQuery1.Eof do begin
Inc(RecCnt);
FieldMD5 := FDQuery1.FieldByName('TEMP_MD5');
SetLength(MD5, FieldMD5.DataSize);
FieldMD5.GetData(MD5);
if (Length(MD5) = Length(MD5_123)) and
(CompareMem(PByte(MD5), PByte(MD5_123), Length(MD5))) then
Memo1.Lines.Add(RecCnt.ToString + ') MD5(123) = ' + MD5ToStr(MD5))
else
Memo1.Lines.Add(RecCnt.ToString + ') ' + MD5ToStr(MD5));
FDQuery1.Next;
end;
end;
正如您在阅读代码时看到的那样,我通过比较包含值(字节数组)的内存,将来自数据库的 MD5 与给定的 MD5 进行比较。
效用函数:
function MD5ToStr(MD5 : TArray<Byte>) : String;
var
B : Byte;
begin
Result := '';
for B in MD5 do
Result := Result + B.ToHexString(2);
end;
我不想将 MD5 hash
存储在 32 字节的字段中,而是将其存储在 16 字节的二进制字段中。 Mysql 字段“TEMP_MD5”定义为 Binary(16)。
带有示例行插入的 MySQL CREATE TABLE 是:
CREATE TABLE `mytable` (
`TEMP_MD5` binary(16) DEFAULT NULL,
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO mytable (TEMP_MD5) VALUES UNHEX("202cb962ac59075b964b07152d234b70") );
示例代码:
假设在MySQL字段中存储了16字节的二进制字段TEMP_MD5,我检索后如何在Delphi代码中比较这个16字节的字段值?
是否可以跳过MySQLHEX/UNHEX内部函数,直接用Delphi代码比较[=44中的16字节二进制字段(32字节字符串) =]?
例如:
FDQuery1.Open( 'SELECT TEMP_MD5 from mytable;' );
if THashMD5.GetHashBytes('123') = fDQuery1.FieldByName('TEMP_MD5').VALUE then
SHOWMESSAGE('MATCHED!');
但是,FieldByName('TEMP_MD5').value 的值似乎与 THashMD5.GetHashString('123') 的值
不匹配另一种使用SELECT语句进行比较的方法也失败了
FDQuery1.Open( 'SELECT TEMP_MD5 mytable ' +
'WHERE (TEMP_MD5=:myvalue)',
[THashMD5.GetHashBytes('123')] );
以上也未能给出FDQuery1.RecordCount = 1
.
基本上我试图将我存储在 MySQL 中的 16 字节二进制文件与一个值进行比较,假设代码中的“123”是否匹配。
我正在使用 Delphi 10.2,明年将升级到 10.4。
下面是一个代码示例,展示了如何将 MD5 写入数据库以及如何读回它并与给定的 MD5 哈希进行比较:
正在插入数据:
procedure TForm1.InsertDataButtonClick(Sender: TObject);
var
MD5 : TArray<Byte>;
begin
MD5 := THashMD5.GetHashBytes('123');
FDConnection1.Connected := TRUE;
FDQuery1.SQL.Text := 'INSERT INTO mytable (TEMP_MD5) VALUES(:MD5)';
FDQuery1.ParamByName('MD5').SetBlobRawData(Length(MD5), PByte(MD5));
FDQuery1.ExecSQL;
Memo1.Lines.Add('Rows affected = ' + FDQuery1.RowsAffected.ToString);
end;
正在读回数据并与给定的哈希值进行比较:
procedure TForm1.ReadDataButtonClick(Sender: TObject);
var
MD5 : TArray<Byte>;
MD5_123 : TArray<Byte>;
FieldMD5 : TField;
RecCnt : Integer;
begin
MD5_123 := THashMD5.GetHashBytes('123');
FDConnection1.Connected := TRUE;
// First version: get all records
// FDQuery1.SQL.Text := 'SELECT TEMP_MD5 FROM mytable';
// Second version: Get only records where TEMP_MD5 is hash('123').
FDQuery1.SQL.Text := 'SELECT TEMP_MD5 FROM mytable WHERE TEMP_MD5 = :MD5';
FDQuery1.ParamByName('MD5').SetBlobRawData(Length(MD5_123), PByte(MD5_123));
// Execute the query
FDQuery1.Open;
RecCnt := 0;
while not FDQuery1.Eof do begin
Inc(RecCnt);
FieldMD5 := FDQuery1.FieldByName('TEMP_MD5');
SetLength(MD5, FieldMD5.DataSize);
FieldMD5.GetData(MD5);
if (Length(MD5) = Length(MD5_123)) and
(CompareMem(PByte(MD5), PByte(MD5_123), Length(MD5))) then
Memo1.Lines.Add(RecCnt.ToString + ') MD5(123) = ' + MD5ToStr(MD5))
else
Memo1.Lines.Add(RecCnt.ToString + ') ' + MD5ToStr(MD5));
FDQuery1.Next;
end;
end;
正如您在阅读代码时看到的那样,我通过比较包含值(字节数组)的内存,将来自数据库的 MD5 与给定的 MD5 进行比较。
效用函数:
function MD5ToStr(MD5 : TArray<Byte>) : String;
var
B : Byte;
begin
Result := '';
for B in MD5 do
Result := Result + B.ToHexString(2);
end;