Adler-32校验和生成 - 为什么使用位和右移运算符

时间:2017-01-18 09:35:03

标签: c# adler32

我找到了在C#中实现Adler32算法的方法,我想使用它,但我不明白部分代码:

有人可以解释一下:

1)为什么在sum1和sum2初始化时使用位运算符

2)为什么sum2被移位?

维基上的Adler32 https://en.wikipedia.org/wiki/Adler-32

&安培;操作说明: (如果两个操作数都存在,则二进制AND运算符会将结果复制到结果中)

private bool MakeForBuffer(byte[] bytesBuff, uint adlerCheckSum)
    {
        if (Object.Equals(bytesBuff, null))
        {
            checksumValue = 0;
            return false;
        }
        int nSize = bytesBuff.GetLength(0);
        if (nSize == 0)
        {
            checksumValue = 0;
            return false;
        }
        uint sum1 = adlerCheckSum & 0xFFFF; // 1) why bit operator is used?
        uint sum2 = (adlerCheckSum >> 16) & 0xFFFF; // 2) why bit operator is used? , why is it shifted?

        for (int i = 0; i < nSize; i++)
        {
            sum1 = (sum1 + bytesBuff[i]) % adlerBase;
            sum2 = (sum1 + sum2) % adlerBase;
        }
        checksumValue = (sum2 << 16) + sum1;
        return true;
    }

1 个答案:

答案 0 :(得分:3)

  

1)为什么使用位运算符?

& 0xFFFF将校验和的两个高字节设置为0,因此sum1只是校验和的低16位。

  

2)为什么使用位运算符? ,为什么会转移?

adlerCheckSum >> 16将16个较高字节向下移动到较低的16个字节,& 0xFFFF与第1步相同 - 它将16个高位设置为0。

示例

adlerChecksum = 0x12345678

adlerChecksum & 0xFFFF = 0x00005678

adlerChecksum >> 16 = 0x????1234

(它应该是C#中的0x00001234,但是其他语言/编译器&#34;包围&#34;并且你会得到0x56781234

(adlerChecksum >> 16) & 0xFFFF = 0x00001234现在您可以确定0x1234,此步骤只是C#中可能不必要的预防措施。

adlerChecksum = 0x12345678
sum1 =          0x00005678
sum2 =          0x00001234

这两项操作合并后只需将UInt32校验和分成两个UInt16

来自adler32 Tag-Wiki:

  

Adler-32是zlib中使用的快速校验和算法,用于验证解压缩的结果。它由模数为65521的两个和组成。以s1 = 1和s2 = 0开始,然后对于每个字节x,s1 = s1 + x,s2 = s2 + s1。这两个和被组合成一个32位值,其中s1在低16位,s2在高16位。