在C语言中计算校验和(16位)

3
我被要求对以下文本进行16位校验和:
"AAAAAAAAAA\nX"
起初,描述似乎想要Fletcher-16校验和。但是,对上述文本执行Fletcher的校验和得到的结果为8aee(十六进制)。示例文件表明模数和算法(减去二的补码)应该在十六进制下输出509d
唯一的其他信息是标准的“每两个字符应添加到校验和中”。
除了使用相应维基百科页面上提供的通用Fletcher-16校验和之外,我还尝试了在此处找到的解决方案:calculating-a-16-bit-checksum,但并未成功。该代码生成了十六进制值4f27
1个回答

2

仅将数据视为大端16位整数数组添加,产生的结果为509d

#include <stdio.h>

int main(void) {
    char data[] = "AAAAAAAAAA\nX";
    int sum = 0;
    int i;
    for(i = 0; data[i] != '\0' && data[i + 1] != '\0'; i += 2) {
        int value = ((unsigned char)data[i] << 8) | (unsigned char)data[i + 1];
        sum = (sum + value) & 0xffff;
    }
    printf("%04x\n", sum);
    return 0;
}

对于一些严谨的程序员:在访问数据时请使用 unsigned char*,否则在恐龙般的非二进制补码机器上,data[i] != '\0'(两个零)和 (unsigned char)data[i] 是不正确的。在 16 位 int 中,(unsigned char)data[i] << 8 存在溢出风险。无论如何最好使用 unsigned sum"%04x" 来避免在 32 位机器上当 sum < 0 时输出 8 位数字。 - chux - Reinstate Monica
@chux-ReinstateMonica 为什么 data[i] != '\0' 是不正确的? - MikeCAT
@Mook 根据每个字节的位置,移位将是 24、16 和 8(以及 0)。 - MikeCAT
@MikeCAT然后我会将每个位移与数组中相应的位置配对,并加入校验和,是吗? - Mook
@Mook 没错,继续实现并进行测试。 - MikeCAT
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接