【发布时间】:2017-11-14 23:53:51
【问题描述】:
我看过几个博客,它们展示了在为一组值生成哈希时如何将结果从 HashBytes 转换为 bigint。这在数据仓库中似乎很常见。这具有将哈希存储为整数的优点,这对于连接非常有用并提供了良好的分区分布。
不过,我想知道这是否是一个好习惯。我注意到使用带有 HashBytes 的 Sha1 会产生 16 字节的结果。由于 bigint 是 8 字节数据类型,这是否会导致在将其转换为 bigint 之前必须将 16 字节截断 8 位?如果是这样,这似乎会增加碰撞的可能性。
我们已经将我们的 varbinary 哈希转换为 bigint 已经有一段时间了,还没有遇到过冲突,但如果上面的假设是正确的,那肯定是运气不好。
为了测试这一点,我尝试转换一些哈希值以查看是否可以从 bigint 恢复到原始哈希值,但无法这样做,这可能表明存在问题(或者我的转换不正确) .
您的数学大师对此有什么想法吗? 提前致谢!
DECLARE @value varchar(5) = '12345'
DECLARE @hash varbinary(max) = hashbytes('SHA1', @Value)
SELECT @hash AS OriginalHash
SELECT CAST(@hash as nvarchar(max)) AS StringHash
SELECT CAST(CAST(@hash as nvarchar(max)) as varbinary(max)) AS StringBackToOriginalHash
SELECT CAST(@hash as bigint) AS BigIntHash
SELECT CAST(CAST(@hash as bigint) as varbinary(max)) AS BigIntBackToOriginalHash
最近 SQL 2016 表明他们将弃用旧的散列算法,我们最终将不得不使用更长的散列值 Sha2_256 和 Sha2_512,这将占用更多空间。如果 bigint 与旧的 Sha1 哈希一样具有抗冲突性,这也是为什么使用 bigint 会很棒的另一个原因。
【问题讨论】:
标签: sql sql-server hash