我在 sql server 2008 R2 中使用 chechsum 函数,我想在 C# 应用程序中获得相同的 int 值。c# 中是否有任何等效方法可以返回诸如 sql 校验和函数之类的值?谢谢
5 回答
在 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;
}
T-SQL 文档没有指定checksum()
在此之外使用什么算法:
CHECKSUM 在其参数列表上计算一个哈希值,称为校验和。哈希值旨在用于构建哈希索引。如果 CHECKSUM 的参数是列,并且在计算的 CHECKSUM 值上构建索引,则结果是哈希索引。这可用于列上的相等搜索。
不太可能计算 MD5 哈希,因为它的返回值(计算的哈希)是一个 32 位整数;MD5 散列的长度为 128 位。
CHECKSUM
文档没有透露它是如何计算哈希的。如果你想要一个可以在 T-SQL 和 C# 中使用的哈希,请从HashBytes支持的算法中选择
如果您需要对 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。
@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 位循环移位,然后是一个与字符字节的异或