【问题标题】:Calculating a 16 bit checksum?计算 16 位校验和?
【发布时间】:2018-10-25 01:20:00
【问题描述】:

使用 c 中的程序读取文件,然后我必须为程序执行 8 位和 16 位校验和。到目前为止,我只完成了 8 位校验和。

这是我理解的

我读取文件并将信息存储在一个字符数组中,最后它采用换行符。所以例如计算 8 位校验和,这就是本质上发生的事情

文件共有 3 个字母(3 个 a 和一个换行符)

所以数组包含 4 个字符 aaa+(newline) (97+97+97+10)

据我了解,我将所有字节添加到数组中,然后执行 % 256,这就是我的校验和。

97 * 3 = //3 a's (small a) 从我理解的 ascii 表中提取

291 + 10 = 301 // + 换行符

301 % 256 = cc 十六进制 //

但是我对如何计算 16 位校验和感到困惑,因为如果它是单个字符数组,我不能一次添加 2 个字符?

任何帮助将不胜感激

【问题讨论】:

  • 我讨厌用问题来回答问题,但为什么是 256?这个数字有什么意义?在检查 16 位时会有什么不同?此外,301 是一个不适合单个字节的数字。这让我想到了unsigned overflow and modulo operations
  • 这是一个简单的校验和算法,还是任何其他修改?这从描述中不清楚。对于简单的校验和只需使用sum & 0xffff(unsigned short)sum (其中unsigned short 表示16 位无符号整数)sum % 65536,如果你喜欢(但我不推荐这最后一个选项;并不是说会有不同的结果,但我认为最好使用& 或重新输入以获得更好的可读性)。当然,只有在这是作业时才使用 sum;认真使用select another hash algorithm.

标签: c checksum


【解决方案1】:

要计算 16 位校验和,以 2 为增量处理数组,并将一个字节放入要添加的值的低位字节,将另一个字节放入高位字节。

uint8_t array[MAX]; // The data gets copied into here
size_t length; // This is the length of the data
uint16_t checksum = 0;
size_t even_length = length - length%2; // Round down to multiple of 2
for (int i = 0; i < even_length; i += 2) {
    uint16_t val = array[i] + 256 * array[i+1];
    checksum += val;
}
if (i < length) { // Last byte if it's odd length
    checksum += array[i];
}

没有必要使用模数,因为无符号整数会自动实现模数运算。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-01
    • 2015-12-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多