我正在尝试将md5 has(通过php生成)与其在SQLExpress数据库中的原始值进行匹配。
我在SQL查询中使用以下函数
master.sys.fn_varbintohexsubstring(0, HASHBYTES('MD5', 'ID'), 1, 0)
其中"ID"是数据库中的字段。
然而,它们似乎都为md5散列返回了不同的值。我一直在使用"12290"作为静态值来测试这一点。
php md5()返回:0bd81786a8ec6ae9b22cb3cb4d88179
以下SQL语句返回相同的输出:
DECLARE @password VARCHAR(255)
SET @password = master.sys.fn_varbintohexsubstring(0, HASHBYTES('MD5', '12290'), 1, 0)
SELECT @password
然而,当我从表中运行以下语句时:
SELECT ID, master.sys.fn_varbintohexsubstring(0, HASHBYTES('MD5', CONVERT(NVARCHAR(255), ID)), 1, 0) AS temp
FROM Clients
ORDER BY ID ASC
与12290的"ID"值匹配的"temp"值返回:1867dce5f1ee1ddb46ff0cc18fc58e03
如果能在这件事上提供任何帮助,我们将不胜感激!
感谢
Python帮我帮你。
>>> from hashlib import md5
>>> md5('1'x002'x002'x009'x000'x00').digest().encode('hex')
'1867dce5f1ee1ddb46ff0ccd1fc58e03'
NVARCHAR是Unicode类型,从上面的实验来看,'12990'
以UTF-16LE的形式存储在您的数据库中:'1'02'09'09'00'0'
。
假设PHP中的数据编码是UTF-8数据,并且您不想更改数据库中的现有数据,这就是修复PHP脚本的方法:
<?php
$password = '12290';
$hash = md5(mb_convert_encoding($password, 'UTF-16LE', 'UTF-8')) . "'n";
echo $hash;
?>
输出:
susam@swift:~$ php utf16le-hash.php
1867dce5f1ee1ddb46ff0ccd1fc58e03
如果PHP中的数据采用其他编码,如ASCII、ISO-8859-1等,则可以相应地将第三个参数更改为mb_convert_encoding
。所有支持的编码列表位于:http://www.php.net/manual/en/mbstring.supported-encodings.php
另请参阅http://www.php.net/manual/en/function.mb-convert-encoding.php
我没有SQL服务器来测试这一点,但CONVERT命令可能正在创建带有240多个尾随空格的NVARCHAR(正如您指定的NVARCAR(255))
尝试将NVARCHAR设置为要测试的ID的长度:
ARE @password VARCHAR(255)
SET @password = master.sys.fn_varbintohexsubstring(0, HASHBYTES('MD5', CONVERT(NVARCHAR(5), '12290')), 1, 0)
SELECT @password
在CONVERT中尝试不同的长度-有什么区别吗?
有两件事最有可能是问题:
- 该行中的ID列的值不完全等于
'12290'
(例如,额外的空白) - 或者
CONVERT
函数产生这样的值
在任何情况下,标准的调试方法都是使用SQL查询来选择该ID字段的字符串长度和CONVERT
的返回值;如果其中一个不等于5
,则发现错误。
或者,您可以对包含数据的有问题的表执行转储,并查看生成的INSERT语句,以查看数据库显示该列中的值是什么