MD5 哈希不同
MD5 hash is Different
在 sql 服务器上:输出: 0x5C8C8AAFE7AE37EA4EBDF8BFA01F82B8
SELECT HASHBYTES('MD5', convert(varchar,getdate(),112)+'mytest@+')
在 JavaScript 上:输出: 5c8c8aafe7ae37ea4ebdf8bfa01f82b8
//to get Md5 Hash bytes
vm.getMd5Hashbytes = function () {
var currentDate = moment().format('YYYYMMDD');
var md5Hash = md5.createHash(currentDate + 'mytest@+');
return md5Hash;
}
问:你能告诉我为什么会有这种差异吗? SQL 服务器将 0x
显示为 prefix.Why?
我不确定还能如何解释它,但它需要的 space 比评论所允许的要多,所以我将 post 它作为答案。
查看您引用的 source code。在最后(第 210 和 212 行),您将看到它将二进制值转换为十六进制字符串(,然后转换为小写,这无关紧要,除非您在最后选择字符串比较).最终结果 = 您的 JavaScript 库 returns 使用类型 string
的表示,格式为十六进制。
另一方面,您的 Sql 函数 HASHBYTES
会产生一个 varbinary
类型的结果( 与字符串 (varchar)).
因此您有 2 种不同的数据类型(每种数据类型都独立存在 space,因为您没有将一种数据拉到另一种数据类型)。您永远不会提到您在哪里进行比较,即:在数据库上还是从数据库中提取到脚本。无论哪种方式进行比较,您都需要转换一种类型,因此您要么比较 2 种字符串类型,要么比较两种二进制类型。如果您不比较相似的类型,您将得到意想不到的结果或 运行 时间异常。
如果您使用字符串 AND 在 JavaScript 中进行比较,那么查看您引用的库,它已经有一个名为 wordToHex
的调用,复制并粘贴它并重新使用它来转换您的Sql 结果为字符串,然后进行字符串比较(不要忘记比较不区分大小写或也将其设为小写)。
编辑
WebApi is black box for me.It is a 3rd party service.I just need to send the security token as mentioned above.
假设该网络 api 接受的类型是 byt[]
将 0x
附加到 javascript 中的字符串,然后将其发送到网络 api 应该像在网络中一样工作 api 然后将传入的参数转换为字节数组并使用正确的类型执行比较。由于这是一个黑盒子,因此无法确定,除非您询问他们接受的类型是否确实是字节数组或对其进行测试。
这纯粹是格式问题。两个版本都产生相同的字节序列。 SQL 在以人类可读的格式呈现这些字节时,服务器和节点有不同的约定。
您可以通过专门告诉 SQL 服务器如何格式化您的二进制数据来获得类似的格式
declare @hashAsBinary varbinary(max)
declare @hashAsText char(32)
set @hashAsBinary = HASHBYTES('MD5', '20160818mytest@+')
set @hashAsText = LOWER(CONVERT(varchar(max), @hashAsBinary, 2))
select @hashAsText
输出:
5c8c8aafe7ae37ea4ebdf8bfa01f82b8
见SQL Server converting varbinary to string
在 sql 服务器上:输出: 0x5C8C8AAFE7AE37EA4EBDF8BFA01F82B8
SELECT HASHBYTES('MD5', convert(varchar,getdate(),112)+'mytest@+')
在 JavaScript 上:输出: 5c8c8aafe7ae37ea4ebdf8bfa01f82b8
//to get Md5 Hash bytes
vm.getMd5Hashbytes = function () {
var currentDate = moment().format('YYYYMMDD');
var md5Hash = md5.createHash(currentDate + 'mytest@+');
return md5Hash;
}
问:你能告诉我为什么会有这种差异吗? SQL 服务器将 0x
显示为 prefix.Why?
我不确定还能如何解释它,但它需要的 space 比评论所允许的要多,所以我将 post 它作为答案。
查看您引用的 source code。在最后(第 210 和 212 行),您将看到它将二进制值转换为十六进制字符串(,然后转换为小写,这无关紧要,除非您在最后选择字符串比较).最终结果 = 您的 JavaScript 库 returns 使用类型 string
的表示,格式为十六进制。
另一方面,您的 Sql 函数 HASHBYTES
会产生一个 varbinary
类型的结果( 与字符串 (varchar)).
因此您有 2 种不同的数据类型(每种数据类型都独立存在 space,因为您没有将一种数据拉到另一种数据类型)。您永远不会提到您在哪里进行比较,即:在数据库上还是从数据库中提取到脚本。无论哪种方式进行比较,您都需要转换一种类型,因此您要么比较 2 种字符串类型,要么比较两种二进制类型。如果您不比较相似的类型,您将得到意想不到的结果或 运行 时间异常。
如果您使用字符串 AND 在 JavaScript 中进行比较,那么查看您引用的库,它已经有一个名为 wordToHex
的调用,复制并粘贴它并重新使用它来转换您的Sql 结果为字符串,然后进行字符串比较(不要忘记比较不区分大小写或也将其设为小写)。
编辑
WebApi is black box for me.It is a 3rd party service.I just need to send the security token as mentioned above.
假设该网络 api 接受的类型是 byt[]
将 0x
附加到 javascript 中的字符串,然后将其发送到网络 api 应该像在网络中一样工作 api 然后将传入的参数转换为字节数组并使用正确的类型执行比较。由于这是一个黑盒子,因此无法确定,除非您询问他们接受的类型是否确实是字节数组或对其进行测试。
这纯粹是格式问题。两个版本都产生相同的字节序列。 SQL 在以人类可读的格式呈现这些字节时,服务器和节点有不同的约定。
您可以通过专门告诉 SQL 服务器如何格式化您的二进制数据来获得类似的格式
declare @hashAsBinary varbinary(max)
declare @hashAsText char(32)
set @hashAsBinary = HASHBYTES('MD5', '20160818mytest@+')
set @hashAsText = LOWER(CONVERT(varchar(max), @hashAsBinary, 2))
select @hashAsText
输出:
5c8c8aafe7ae37ea4ebdf8bfa01f82b8
见SQL Server converting varbinary to string