以下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
答案 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()?