checksum(),binary_checksum() 应该如何使用

最近看到一个有趣的系统函数应用问题。 

起因是A使用checksum(),对两行数据是否完全一致进行判断。后来使用了binary_checksum() 进行判断。
但在实际的运行过程中,发现会出现哈希碰撞的问题。程序表现不稳定。

测试了一下 

SELECT CHECKSUM(9),
       CHECKSUM('asdfa', 9),
       CHECKSUM(123, GETDATE(), 'xyz'),
	   BINARY_CHECKSUM(9),
	   BINARY_CHECKSUM('asdfa', 9),
       BINARY_CHECKSUM(123, GETDATE(), 'xyz');	

 

  • 判断两行信息是否一致的逻辑,大概是这样:
DECLARE @i TABLE(id INT,name VARCHAR(10),age TINYINT)

INSERT INTO @i
(
	id,
	name,
	age
)
SELECT 1,'张三',12
UNION all
SELECT 2,'李四',15
UNION all
SELECT 1,'张三',12
	UNION all
SELECT 1,'王五',22


SELECT CHECKSUM(*),BINARY_CHECKSUM(*) FROM @i

如果判定这两个值有相等的,即可判定这两行是信息是一致的。(如果有很多列,这个用法是不是很酷炫,但是....)

 

碰撞

在数学的角度来看,校验和一样,并不意味着校验前的信息是一样的。

这里涉及一个概念的理解,什么是校验和(checksum)

简单理解过来,就是校验和是将输入数据(比如长度为2048bytes)进行了缩短化处理到4 bytes(返回值是int)。

int 范围(-2147483648 ~ 2147483647)尚且有限,那么在各种输入的情况下, 缩短化处理到这个范围,也一定会出现重复(碰撞问题

SELECT CHECKSUM(9,1.0),CHECKSUM(9,-1.0),BINARY_CHECKSUM(3,4.1),BINARY_CHECKSUM(3,-4.1)

测试一个足够长的例子

DECLARE @k nvarchar(MAX) ='你好,今天是星期一你好,今天是星期一你好,今天是星期一你好,
今天是星期一你好,今天是星期一你好,今天是星期一你好,今天是星期一你好,今天是星期一你好,
今天是星期一你好,今天是星期一你好,今天是星期一你好,今天是星期一你好,今天是星期一你好,
今天是星期一你好,今天是星期一你好,今天是星期一你好,今天是星期一你好,今天是星期一你好,
今天是星期一你好,今天是星期一你好,今天是星期一你好,今天是星期一你好,今天是星期一你好,
今天是星期一你好,今天是星期一你好,今天是星期一你好,今天是星期一你好,今天是星期一你好,
今天是星期一你好,今天是星期一你好,今天是星期一'

select binary_checksum(@k),
       binary_checksum(@k + '真的吗?')

注意,最后一列,即便加上了额外的信息,计算出来的校验和也跟之前的一样。又一次碰撞了。 

 

总结:

checksum,binary_checksum 只能用于一种情况:如果校验和不相同,那么输入一定不相同。

反之,则不成立。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值