11

我在 sql server 2008 R2 中使用 chechsum 函数,我想在 C# 应用程序中获得相同的 int 值。c# 中是否有任何等效方法可以返回诸如 sql 校验和函数之类的值?谢谢

4

5 回答 5

15

在 SQL Server 论坛上,在这个页面上,它声明:

SQL Server 中内置的 CHECKUM 函数建立在一系列 4 位左旋转异或操作之上。有关更多说明,请参阅此帖子

我能够将 BINARY_CHECKSUM 移植到 c# 并且它似乎正在工作......我稍后会看普通的 CHECKSUM......

private int SQLBinaryChecksum(string text)
{
    long sum = 0;
    byte overflow;
    for (int i = 0; i < text.Length; i++)
    {
        sum = (long)((16 * sum) ^ Convert.ToUInt32(text[i]));
        overflow = (byte)(sum / 4294967296);
        sum = sum - overflow * 4294967296;
        sum = sum ^ overflow;
    }

    if (sum > 2147483647)
        sum = sum - 4294967296;
    else if (sum >= 32768 && sum <= 65535)
        sum = sum - 65536;
    else if (sum >= 128 && sum <= 255)
        sum = sum - 256;

    return (int)sum;
}
于 2013-09-18T16:45:46.250 回答
2

T-SQL 文档没有指定checksum()在此之外使用什么算法:

CHECKSUM 在其参数列表上计算一个哈希值,称为校验和。哈希值旨在用于构建哈希索引。如果 CHECKSUM 的参数是列,并且在计算的 CHECKSUM 值上构建索引,则结果是哈希索引。这可用于列上的相等搜索。

不太可能计算 MD5 哈希,因为它的返回值(计算的哈希)是一个 32 位整数;MD5 散列的长度为 128 位。

于 2013-09-18T16:54:40.523 回答
2

CHECKSUM文档没有透露它是如何计算哈希的。如果你想要一个可以在 T-SQL 和 C# 中使用的哈希,请从HashBytes支持的算法中选择

于 2013-09-18T16:54:52.883 回答
2

如果您需要对 GUID 进行校验和,请将 dna2 的答案更改为:

private int SQLBinaryChecksum(byte[] text)

对于字节数组,SQL 中的值将与 C# 中的值匹配。去测试:

var a = Guid.Parse("DEAA5789-6B51-4EED-B370-36F347A0E8E4").ToByteArray();
Console.WriteLine(SQLBinaryChecksum(a));

与 SQL:

select BINARY_CHECKSUM(CONVERT(uniqueidentifier,'DEAA5789-6B51-4EED-B370-36F347A0E8E4'))

两个答案都是-1897092103。

于 2014-12-17T21:56:30.507 回答
0

@Dan 的 BinaryChecksum 实现可以在 c# 中大大简化为

int SqlBinaryChecksum(string text)
{
    uint accumulator = 0;
    for (int i = 0; i < text.Length; i++)
    {
        var leftRotate4bit = (accumulator << 4) | (accumulator >> -4);
        accumulator = leftRotate4bit ^ text[i];
    }
    return (int)accumulator;
}

这也使得算法在做什么更清楚。对于每个字符,一个 4 位循环移位,然后是一个与字符字节的异或

于 2020-11-25T21:08:56.830 回答