Adler-32 校验和生成 - 为什么使用位和右移运算符
Adler-32 checksum generating - why bit and shift right operator are used
我找到了在 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) why bit operator is used?
& 0xFFFF
将校验和的两个高字节设置为 0,因此 sum1
只是校验和的低 16 位。
2) why bit operator is used? , why is it shifted?
adlerCheckSum >> 16
将高 16 字节向下移动到低 16 字节,& 0xFFFF
与第一步相同 - 将高 16 位设置为 0。
例子
adlerChecksum = 0x12345678
adlerChecksum & 0xFFFF = 0x00005678
adlerChecksum >> 16 = 0x????1234
(在 C# 中应该是 0x00001234
但在其他语言/编译器中 "wrap the bits around" 你会得到 0x56781234
)
(adlerChecksum >> 16) & 0xFFFF
= 0x00001234
现在你可以确定它是 0x1234
,这一步只是一个预防措施,在 C# 中可能是不必要的。
adlerChecksum = 0x12345678
sum1 = 0x00005678
sum2 = 0x00001234
这两个操作组合简单地将 UInt32
校验和分成两个 UInt16
。
来自 adler32 Tag-Wiki:
Adler-32 is a fast checksum algorithm used in zlib to verify the results of decompression. It is composed of two sums modulo 65521. Start with s1 = 1 and s2 = 0, then for each byte x, s1 = s1 + x, s2 = s2 + s1. The two sums are combined into a 32-bit value with s1 in the low 16 bits and s2 in the high 16 bits.
我找到了在 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) why bit operator is used?
& 0xFFFF
将校验和的两个高字节设置为 0,因此 sum1
只是校验和的低 16 位。
2) why bit operator is used? , why is it shifted?
adlerCheckSum >> 16
将高 16 字节向下移动到低 16 字节,& 0xFFFF
与第一步相同 - 将高 16 位设置为 0。
例子
adlerChecksum = 0x12345678
adlerChecksum & 0xFFFF = 0x00005678
adlerChecksum >> 16 = 0x????1234
(在 C# 中应该是 0x00001234
但在其他语言/编译器中 "wrap the bits around" 你会得到 0x56781234
)
(adlerChecksum >> 16) & 0xFFFF
= 0x00001234
现在你可以确定它是 0x1234
,这一步只是一个预防措施,在 C# 中可能是不必要的。
adlerChecksum = 0x12345678
sum1 = 0x00005678
sum2 = 0x00001234
这两个操作组合简单地将 UInt32
校验和分成两个 UInt16
。
来自 adler32 Tag-Wiki:
Adler-32 is a fast checksum algorithm used in zlib to verify the results of decompression. It is composed of two sums modulo 65521. Start with s1 = 1 and s2 = 0, then for each byte x, s1 = s1 + x, s2 = s2 + s1. The two sums are combined into a 32-bit value with s1 in the low 16 bits and s2 in the high 16 bits.