有趣的是,我可以在几乎所有语言中找到互联网校验和的实现,除了C#。有没有人有要分享的实现?
请记住,internet protocol指定:
校验和字段是报头中所有16位字的补码和的16位补码。为了计算校验和,校验和字段的值为零。
更多的解释可以从Dr. Math找到。
有一些efficiency pointers可用,但这对我来说并不是一个很大的问题。
请将您的测试包括在内!(编辑:关于测试他人代码的有效评论-但我正在退出协议,没有自己的测试向量,宁愿进行单元测试,而不是投入生产,看看它是否与当前正在使用的代码匹配!;-)
编辑:下面是我想出来的一些单元测试。它们测试一个遍历整个字节集合的扩展方法。如果你在测试中发现错误,请评论。
[TestMethod()]
public void InternetChecksum_SimplestValidValue_ShouldMatch()
{
IEnumerable<byte> value = new byte[1]; // should work for any-length array of zeros
ushort expected = 0xFFFF;
ushort actual = value.InternetChecksum();
Assert.AreEqual(expected, actual);
}
[TestMethod()]
public void InternetChecksum_ValidSingleByteExtreme_ShouldMatch()
{
IEnumerable<byte> value = new byte[]{0xFF};
ushort expected = 0xFF;
ushort actual = value.InternetChecksum();
Assert.AreEqual(expected, actual);
}
[TestMethod()]
public void InternetChecksum_ValidMultiByteExtrema_ShouldMatch()
{
IEnumerable<byte> value = new byte[] { 0x00, 0xFF };
ushort expected = 0xFF00;
ushort actual = value.InternetChecksum();
Assert.AreEqual(expected, actual);
}发布于 2010-02-05 00:00:05
好吧,我从一个旧的代码库中挖掘出一个实现,它通过了我在问题中指定的测试,所以它是这样的(作为一个扩展方法):
public static ushort InternetChecksum(this IEnumerable<byte> value)
{
byte[] buffer = value.ToArray();
int length = buffer.Length;
int i = 0;
UInt32 sum = 0;
UInt32 data = 0;
while (length > 1)
{
data = 0;
data = (UInt32)(
((UInt32)(buffer[i]) << 8)
|
((UInt32)(buffer[i + 1]) & 0xFF)
);
sum += data;
if ((sum & 0xFFFF0000) > 0)
{
sum = sum & 0xFFFF;
sum += 1;
}
i += 2;
length -= 2;
}
if (length > 0)
{
sum += (UInt32)(buffer[i] << 8);
//sum += (UInt32)(buffer[i]);
if ((sum & 0xFFFF0000) > 0)
{
sum = sum & 0xFFFF;
sum += 1;
}
}
sum = ~sum;
sum = sum & 0xFFFF;
return (UInt16)sum;
}发布于 2010-02-03 06:07:42
我知道我把它藏在某个地方了。http://cyb3rspy.wordpress.com/2008/03/27/ip-header-checksum-function-in-c/
https://stackoverflow.com/questions/2188060
复制相似问题