Sql server 校验和与校验和:什么';算法是什么?

Sql server 校验和与校验和:什么';算法是什么?,sql-server,sql-server-2008,checksum,Sql Server,Sql Server 2008,Checksum,我们对sql server中的某些数据执行校验和,如下所示: declare @cs int; select @cs = CHECKSUM_AGG(CHECKSUM(someid, position)) from SomeTable where userid = @userId group by userid; 然后与客户端共享此数据。我们希望能够在客户端重复校验和。。。但是,似乎没有关于如何计算上述函数中的校验和的任何信息。有人能给我一些启发吗?校验和

我们对sql server中的某些数据执行校验和,如下所示:

declare @cs int;
select 
    @cs = CHECKSUM_AGG(CHECKSUM(someid, position))
from 
    SomeTable
where 
    userid = @userId
group by 
    userid;

然后与客户端共享此数据。我们希望能够在客户端重复校验和。。。但是,似乎没有关于如何计算上述函数中的校验和的任何信息。有人能给我一些启发吗?

校验和函数不能提供高质量的校验和,IMO在大多数情况下都是无用的。据我所知,该算法尚未公布。如果您想检查自己是否可以复制,请使用HashBytes函数和标准的、已发布的算法之一,如MD5或SHA。

在SQL Server论坛上,这里指出:


SQL Server中的内置校验和函数是基于一系列4位左旋转异或操作构建的。更多解释请参见此。

/SQL和C的快速哈希和

     private Int64 HASH_ZKCRC64(byte[] Data)
    {
        Int64 Result = 0x5555555555555555;
        if (Data == null || Data.Length <= 0) return 0;
        int SizeGlobalBufer = 8000;
        int Ost = Data.Length % SizeGlobalBufer;
        int LeftLimit = (Data.Length / SizeGlobalBufer) * SizeGlobalBufer;

        for (int i = 0; i < LeftLimit; i += 64)
        {
            Result = Result
            ^ BitConverter.ToInt64(Data, i)
            ^ BitConverter.ToInt64(Data, i + 8)
            ^ BitConverter.ToInt64(Data, i + 16)
            ^ BitConverter.ToInt64(Data, i + 24)
            ^ BitConverter.ToInt64(Data, i + 32)
            ^ BitConverter.ToInt64(Data, i + 40)
            ^ BitConverter.ToInt64(Data, i + 48)
            ^ BitConverter.ToInt64(Data, i + 56);
             if ((Result & 0x0000000000000080) != 0)
             Result = Result ^ BitConverter.ToInt64(Data, i + 28); 
        }

        if (Ost > 0)
        {
           byte[] Bufer = new byte[SizeGlobalBufer];
           Array.Copy(Data, LeftLimit, Bufer, 0, Ost);
           for (int i = 0; i < SizeGlobalBufer; i += 64)
           {
               Result = Result
               ^ BitConverter.ToInt64(Bufer, i)
               ^ BitConverter.ToInt64(Bufer, i + 8)
               ^ BitConverter.ToInt64(Bufer, i + 16)
               ^ BitConverter.ToInt64(Bufer, i + 24)
               ^ BitConverter.ToInt64(Bufer, i + 32)
               ^ BitConverter.ToInt64(Bufer, i + 40)
               ^ BitConverter.ToInt64(Bufer, i + 48)
               ^ BitConverter.ToInt64(Bufer, i + 56);
               if ((Result & 0x0000000000000080)!=0)
               Result = Result ^ BitConverter.ToInt64(Bufer, i + 28); 
           }
        }

        byte[] MiniBufer = BitConverter.GetBytes(Result);
        Array.Reverse(MiniBufer);
        return BitConverter.ToInt64(MiniBufer, 0);

        #region SQL_FUNCTION
        /*  CREATE FUNCTION [dbo].[HASH_ZKCRC64] (@data as varbinary(MAX)) Returns bigint
            AS
            BEGIN
            Declare @I64 as bigint Set @I64=0x5555555555555555
            Declare @Bufer as binary(8000)
            Declare @i as int Set @i=1
            Declare @j as int 
            Declare @Len as int Set @Len=Len(@data)     

            if ((@data is null) Or (@Len<=0)) Return 0

              While @i<=@Len
              Begin
               Set @Bufer=Substring(@data,@i,8000)
               Set @j=1
                   While @j<=8000
                   Begin
                    Set @I64=@I64 
                    ^ CAST(Substring(@Bufer,@j,   8) as bigint) 
                    ^ CAST(Substring(@Bufer,@j+8, 8) as bigint) 
                    ^ CAST(Substring(@Bufer,@j+16,8) as bigint)
                    ^ CAST(Substring(@Bufer,@j+24,8) as bigint)
                    ^ CAST(Substring(@Bufer,@j+32,8) as bigint)
                    ^ CAST(Substring(@Bufer,@j+40,8) as bigint)
                    ^ CAST(Substring(@Bufer,@j+48,8) as bigint)
                    ^ CAST(Substring(@Bufer,@j+56,8) as bigint)
                    if @I64<0 Set @I64=@I64 ^ CAST(Substring(@Bufer,@j+28,8) as bigint)      
                    Set @j=@j+64    
                   End;  
               Set @i=@i+8000
              End
            Return @I64
            END
         */
        #endregion

   }
private Int64 HASH_ZKCRC64(字节[]数据)
{
Int64结果=0x5555;
if(Data==null | | Data.Length 0)
{
字节[]Bufer=新字节[SizeGlobalBufer];
复制(数据、LeftLimit、Bufer、0、Ost);
对于(int i=0;i如果(@data为null)或(@Len我找到了
校验和
算法,至少对于ASCII字符是这样。我用JavaScript创建了一个证明(请参阅)

简言之:向左旋转4位,对每个字符进行异或运算。诀窍是计算出“异或代码”。下面是这些代码的表:

var xorcode=[
0, 1, 2, 3, 4, 5, 6, 7,
8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23,
24, 25, 26, 27, 28, 29, 30, 31,
0, 33, 34, 35, 36, 37, 38, 39,  //  !"#$%&'
40, 41, 42, 43, 44, 45, 46, 47,  // ()*+,-./
132, 133, 134, 135, 136, 137, 138, 139,  // 01234567
140, 141, 48, 49, 50, 51, 52, 53, 54,  // 89:;?@
142、143、144、145、146、147、148、149、//ABCDEFGH
150151152153154155156157,//IJKLMNOP
158159160161162163164165,//qrstuvx
166、167、55、56、57、58、59、60、//YZ[\]^_`
142、143、144、145、146、147、148、149、//abcdefgh
150151152153154155156157,//ijklmnop
158159160161162163164165,//qrstuvx
166、167、61、62、63、64、65、66、//yz{124;}~
];
需要注意的主要问题是对字母数字的偏见(它们的代码是相似的和升序的)。英语字母使用相同的代码,不管大小写


我没有测试过高位码(128+)和Unicode。

我怀疑使用的校验和算法太差,以至于MS不好意思告诉任何人它是什么!