【问题标题】:Which algorithm is used for Checksum(), Binary_Checksum() and CHECKSUM_AVG() function in SQL Server?SQL Server 中的 Checksum()、Binary_Checksum() 和 CHECKSUM_AVG() 函数使用哪种算法?
【发布时间】:2018-03-18 06:28:16
【问题描述】:

Checksum()Binary_Checksum()CHECKSUM_AVG() 函数由 SQL Server 提供,用于基于表达式或列列表构建哈希索引。
这有助于确定行是否已更改。然后可以使用该机制来识别记录是否已更新。

我发现了许多为不同值生成相同哈希值的冲突示例。我们如何识别这些函数的碰撞条件。

任何人都必须知道使用哪种算法或技术来生成/计算没有哈希冲突的哈希?

【问题讨论】:

  • 您的问题格式不正确。描述更多并检查 StackOverflow 指南请分享一些代码示例。你面临什么问题。
  • 我已经尝试过 Checksum() 和 Binary_checksum() 函数来生成哈希值,但对于某些值,它会生成重复的哈希值。所以哈希值是冲突的。你有什么线索可以在不冲突哈希值的情况下生成哈希。

标签: sql-server tsql hash checksum


【解决方案1】:

根据sqlTeam上CHECKSUM weakness explained的文章:

SQL Server 中内置的 CHECKUM 函数是建立在一系列 4 位左旋异或操作之上的。

Peter Larsson 发布的forum post from 2006(在文章中也有链接)包含计算校验和的 sql 用户定义函数。该帖子的作者声称与 SQL Server 的内置函数 100% 兼容(我自己没有测试过)。

如果链接失效,这里是相关部分的副本:

使用 text/varchar/image 数据,调用 SELECT BINARY_CHECKSUM('abcdefghijklmnop'), dbo.fnPesoBinaryChecksum('abcdefghijklmnop') 整数数据,调用SELECT BINARY_CHECKSUM(123)dbo.fnPesoBinaryChecksum(CAST(123 AS VARBINARY)) 我还没有弄清楚如何计算大于 255 的整数的校验和。
CREATE FUNCTION dbo.fnPesoBinaryChecksum
(
    @Data IMAGE
)
RETURNS INT
AS

BEGIN
    DECLARE @Index INT,
        @MaxIndex INT,
        @SUM BIGINT,
        @Overflow TINYINT

    SELECT  @Index = 1,
        @MaxIndex = DATALENGTH(@Data),
        @SUM = 0

    WHILE @Index <= @MaxIndex
        SELECT  @SUM = (16 * @SUM) ^ SUBSTRING(@Data, @Index, 1),
            @Overflow = @SUM / 4294967296,
            @SUM = @SUM - @Overflow * 4294967296,
            @SUM = @SUM ^ @Overflow,
            @Index = @Index + 1

    IF @SUM > 2147483647
        SET @SUM = @SUM - 4294967296
    ELSE IF @SUM BETWEEN 32768 AND 65535
        SET @SUM = @SUM - 65536
    ELSE IF @SUM BETWEEN 128 AND 255
        SET @SUM = @SUM - 256

    RETURN @SUM
END

其实这是对 MS 功能的改进,因为它接受 TEXT 和 IMAGE 数据。

CREATE FUNCTION [dbo].[fnPesoTextChecksum]
(
    @Data TEXT
)
RETURNS INT
AS

BEGIN
    DECLARE @Index INT,
        @MaxIndex INT,
        @SUM BIGINT,
        @Overflow TINYINT

    SELECT  @Index = 1,
        @MaxIndex = DATALENGTH(@Data),
        @SUM = 0

    WHILE @Index <= @MaxIndex
        SELECT  @SUM = (16 * @SUM) ^ ASCII(SUBSTRING(@Data, @Index, 1)),
            @Overflow = @SUM / 4294967296,
            @SUM = @SUM - @Overflow * 4294967296,
            @SUM = @SUM ^ @Overflow,
            @Index = @Index + 1

    IF @SUM > 2147483647
        SET @SUM = @SUM - 4294967296
    ELSE IF @SUM BETWEEN 32768 AND 65535
        SET @SUM = @SUM - 65536
    ELSE IF @SUM BETWEEN 128 AND 255
        SET @SUM = @SUM - 256

    RETURN  @SUM
END

另一本好书是 Thomas Kejser 的 Exploring Hash Functions In SQL Server,作者在其中检查了 sql server 中内置的哈希函数的速度和质量。

【讨论】:

    【解决方案2】:

    BINARY_CHECKSUM 的 PHP 实现:

    $input = 'binary string';
    $sum = 0;
    for ($i = 0; $i < strlen($input); $i++) {
        $sum = ($sum << 4) ^ ord($in[$i]);
        $sum = ($sum & 0xffffffff) ^ ($sum >> 32);
    }
    return $sum > 0x7fffffff ? $sum - 0x100000000 : $sum;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-02-28
      • 1970-01-01
      • 1970-01-01
      • 2011-05-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多