为什么checksum()为不同的字符串返回相同的值

时间:2017-01-30 22:37:30

标签: sql-server sql-server-2012

以下SQL及其结果显示不同的字符串获得了相同的checksum结果。为什么呢?

select  str ,
        binary_checksum(str) binary_checksum,
        checksum(str) checksum,
        hashbytes('md5', str) md5
from    ( values ( '2Volvo Director 20'), ( '3Volvo Director 30'), ( '4Volvo Director 40') ) 
        t ( str ) 
str                binary_checksum checksum    md5
------------------ --------------- ----------- --------------------------------------------
2Volvo Director 20 -1356512636     -383039272  0xB9BD78BCF70FAC36AF14FFF589767278
3Volvo Director 30 -1356512636     -383039272  0xF039462F3D15B162FFCDB6125D290826
4Volvo Director 40 -1356512636     -383039272  0xFAF315CDA6E453CCC09838CFB129EE74

2 个答案:

答案 0 :(得分:0)

您当前的数据库排序规则很可能是CP1,对于2016年或2017年以前的SQL Server版本,默认使用SQL_Latin1_General_CP1_CI_AI(根据经验,我无法从任何官方来源确认该排序规则)具有相同的描述

  

Latin1常规,不区分大小写,不区分重音,   kanatype不敏感,对Unicode数据不区分宽度,SQL Server   针对非Unicode数据的代码页1252上的排序顺序54

如果将其更改为Latin1_General_CI_AI之类的Unicode敏感排序规则,它将为您的值返回不同的校验和,这两个排序规则之间的唯一区别是Unicode部分。

  

Latin1常规,不区分大小写,不区分重音,   不区分假名类型,不区分宽度

select  str ,
        binary_checksum(str) binary_checksum,
        checksum(str) checksum,
        hashbytes('md5', str) md5
from    ( values ( '2Volvo Director 20'COLLATE Latin1_General_CI_AI), ( '3Volvo Director 30'COLLATE Latin1_General_CI_AI), ( '4Volvo Director 40'COLLATE Latin1_General_CI_AI) ) 
        t ( str ) 

使用NVarchar还会返回不同的校验和,从而确认这是Unicode问题

select  str ,
        binary_checksum(str) binary_checksum,
        checksum(str) checksum,
        hashbytes('md5', str) md5
from    ( values ( N'2Volvo Director 20'), ( N'3Volvo Director 30'), ( N'4Volvo Director 40') ) 
        t ( str ) 

我找不到任何资料可以解释为什么数字被视为Unicode数据

答案 1 :(得分:0)

SQL CHECKSUM()和MD5为Hash functions。哈希是一种单向算法,可以采用任意数量的字符/字节并返回固定数量的字符/字节。

这意味着无论您输入的是1个字符还是一本完整的书(《战争与和平》),您都将获得相同的回复时间。因此,输入是无数个组合,而输出是有限的。基于此,不可避免地要为不同的值获得相同的哈希值。它称为Hash collision。好的哈希算法会尝试缓解这种情况,从而很难找到这些冲突值。

但是关于散列的足够理论。这正是您问题的答案。什么是issue with CHECKSUM()

相关问题