C Internet校验和功能是否移动8位

C Internet校验和功能是否移动8位,c,checksum,rfc,C,Checksum,Rfc,这是我对(RFC 1071)的实现: 当遇到奇数字节时,为什么我们不需要像这样左移8位,而RFC也不需要左移8位。为什么?我想这是对的 sum += (*(unsigned char*)addr << 8) & 0xFF00; sum+=(*(unsigned char*)addr您从RFC发布的代码对于littleendian机器是正确的。在bigendian机器上,您的移位解决方案是必要的 如果字节数为奇数,则会在序列的末尾添加一个(理论上)0字节。因此,最后一个字节

这是我对(RFC 1071)的实现:

当遇到奇数字节时,为什么我们不需要像这样左移8位,而RFC也不需要左移8位。为什么?我想这是对的

 sum += (*(unsigned char*)addr << 8) & 0xFF00;

sum+=(*(unsigned char*)addr您从RFC发布的代码对于littleendian机器是正确的。在bigendian机器上,您的移位解决方案是必要的

如果字节数为奇数,则会在序列的末尾添加一个(理论上)0字节。因此,最后一个字节XX应被视为具有字节序列XX 00的短字节,需要根据机器的端度进行不同的处理

以下是一种正确处理任意端点的方法:

if (count > 0) {
    unsigned char temp[2];
    temp[0] = *(unsigned char *) addr;
    temp[1] = 0;
    sum    += *(unsigned short *) temp;
}

对于那些不相信RFC代码是错误的人,我建议你们,很明显littleendian和bigendian的情况必须以我描述的方式进行不同的处理。linux代码稍微复杂一点,因为它处理未对齐的缓冲区。

Short至少是16位,不能保证它不是32位或64位。 您应该使用来自的uint\U 16t

你需要改变一下,最后一个补充是

{
    uint16_t tmp=0;
    memcpy(addr,&tmp,1);
    sum += tmp;
}
这保持了直线,所以,在一个小小的endian Machine上,它没有移动 但在大端上,它被比作一个字符

sum += ( *addr && *((uint16_t*)"\xff"));
但是,除非您有一些技巧来对齐字符串,否则该代码可能无法工作

请注意,结果是按网络字节顺序排列的,因此 如果需要主机字节顺序,请使用 函数进行转换

foo=compute_checksum(blah,blah_size);
printf("the internet checksum is %04h\n",(int)ntohs(foo));

请为您正在使用的语言添加一个标记。您指的是哪种RFC?@Ja͢ck,我读过这篇文章。我能说左移位的8位是不必要的吗?不管它是什么样的尾数。如果我使用相同的校验和方法对字节进行校验和,结果将是相同的。例如,sum+=*(无符号字符*)addr;添加一个奇数字节ABCD+AB00(littleEndian)或者ABCDD+00AB(bigEndian),虽然不正常,但可以检查。如果我使用自己的校验和方法接收数据包,则可以接收数据包。如果我想将数据包发送给其他人,则应考虑endianess。对吗?现在,网络设备(以太网卡、路由器等)在硬件中执行校验和运算,如果数据包的校验和运算错误,则会拒绝数据包。因此,除了在同一台机器上从一个进程发送到另一个进程之外,您甚至无法将数据包发送给自己。如果我更改代码以解算两个端的总和+=(*addr)&0xFF00;这与这两种情况兼容吗?*addr包含16位。littleEndian:CDAB+00FF bigEndian:ABCD+FF00 RFC中的代码不关心您的机器是哪一个endian,internet是big endian,但正如已经演示的,当每个校验和字节都传送到其相邻字节时,该代码适用于任意一个endian。“关于符号的魔力。"我不明白。网络字节是bigEndian,如果有一个奇数字节,只需添加它,不需要将其更改为XX00?只需添加00XX?例如,0x123456=>1234+0056,你能详细解释一下吗?@JS1是的,我有点困惑,并且误读了原始帖子。RFC。已经做了更正。@Jasen无需担心。我只是不想要错误的inf有很多IP校验和的实现都是完全按照RFC代码进行的,而没有提到代码只适用于little endian。如果你在互联网上搜索,你会发现大多数都是这样的。
foo=compute_checksum(blah,blah_size);
printf("the internet checksum is %04h\n",(int)ntohs(foo));