MD5哈希值不同

时间:2016-08-18 16:35:45

标签: javascript angularjs sql-server md5

在sql server上:输出: 0x5C8C8AAFE7AE37EA4EBDF8BFA01F82B8

SELECT HASHBYTES('MD5', convert(varchar,getdate(),112)+'mytest@+')

关于JavaScript:Out put: 5c8c8aafe7ae37ea4ebdf8bfa01f82b8

        //to get Md5 Hash bytes
        vm.getMd5Hashbytes = function () {
            var currentDate = moment().format('YYYYMMDD');
             var md5Hash = md5.createHash(currentDate + 'mytest@+');
             return md5Hash;
        }

angular-md5 module

问:你能告诉我为什么会有这种差异吗? SQL服务器显示0x作为前缀。为什么?

2 个答案:

答案 0 :(得分:1)

我不确定如何解释它,但它会比评论所允许的空间更多,所以我会将其作为答案发布。

查看您引用的source code。在最后(第210和212行),您将看到它将二进制值转换为十六进制字符串(然后是小写,除非您选择最后的字符串比较,否则无关紧要)。最终结果=您的JavaScript库使用格式为十六进制的类型string返回表示。

另一方面,您的Sql函数HASHBYTES会生成varbinary类型的结果(与字符串(varchar)不同的类型)。

所以你有两种不同的数据类型(每个都存在于自己的空间中,因为你还没有把它们拉到另一个)。你永远不会提到你在做比较的地方,即:在数据库上,或者你是从数据库拉到脚本。无论哪种方式进行比较,您都需要转换一种类型,以便比较两种字符串类型或比较两种二进制类型。如果您不比较类似的类型,您将获得意外结果或运行时异常。

如果您在JavaScript中使用字符串AND进行比较,那么请查看您正在引用的库,它已经有一个名为wordToHex的调用,复制并粘贴它并重复使用它将您的Sql结果转换为字符串然后进行字符串比较(不要忘记比较不区分大小写或者使其小写)。

修改

  

WebApi对我来说是黑盒子。它是第三方服务。我只需要发送上面提到的安全令牌。

假设该网络API所接受的类型是byt[]在javascript中将0x附加到您的字符串中,然后将其发送到网络API应该可以正常工作,因为在网络API中将转换传入的参数作为字节数组并使用正确的类型执行比较。由于这是一个黑盒子,除非你问他们接受的类型是否确实是一个字节数组或测试它,否则无法确定。

答案 1 :(得分:1)

这纯粹是格式化问题。两个版本都产生相同的字节序列。当以人类可读的格式呈现这些字节时,SQL Server和节点只有不同的约定。

您可以通过专门告诉SQL Server如何格式化二进制数据来获得类似的格式

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