美文网首页
Checksum算法(累加校验和)

Checksum算法(累加校验和)

作者: 三也视界 | 来源:发表于2024-05-19 17:12 被阅读0次

校验和计算:

1、校验数据以16bit为单位进行累加求和,校验数据需为偶数字节,奇数字节末尾填充0变为偶数字节。
2、如果累加和超过16bit,产生了进位,需将高16bit和低16bit累加求和。
3、循环步骤2,直至未产生进位为止。
4、累加和取反得到校验和。

校验和验证

1、校验数据16bit为单位进行累加求和,校验数据需为偶数字节,奇数字节末尾填充0变为偶数字节。
2、如果累加和超过16bit,产生了进位,需将高16bit和低16bit累加求和。
3、循环步骤2,直至未产生进位为止。
4、累加和和校验和相加得到0xffff,校验成功,否则失败。

一个简单的例子

image.png

对于上图的例子,发送数据7、11、12、0、6,五位数据。
发送时的校验和计算(左边)
1)上面是最简单的例子,7、11、12、0、6为奇数位,所以末尾补充0。求和得到了36=100100
2)100100 超过了16,需要把高位10和低位0100进行累加,即得到了0110
3)已无进位,无需循环,执行4
4)0110取反为1001 十进制为9,即发送的数据为7、11
12、0、6、9

接收时的校验和验证(右边)
1)对接收到的数据7、11
12、0、6、9,为偶数位无需补0,直接求和为45=101101
2)101101 超过了16,需要把高位10和低位1101 进行累加,即得到了1111
3)已无进位,无需循环,执行4
4)1111取反为0000 为0,即校验成功,数据为正确数据

另一个例子

如计算下面一段数据的checksum,数据为16进制;

45 00 00 3c 00 00 00 00 40 11 \color{red}{6d} \color{red}{36} c0 a8 2b c3 08 08 08 08 11

红色的6d 36为checksum字段,先把checksum设0,数据分组,补0,整理完后数据如下,中间checksum设置为0,最后补1byte 0;

4500 003c 0000 0000 4011 \color{red}{0000} c0a8 2bc3 0808 0808 1100

计算:4500+003c+0000+0000+4011+\color{red}{0000}+c0a8+2bc3+0808+0808+1100 = 192C8
高低16bit相加: 1 + 92C8 = 92C9
取反: ~92C9 = 6D36
最后所得数据为:45 00 00 3c 00 00 00 00 40 11 \color{red}{6d} \color{red}{36} c0 a8 2b c3 08 08 08 08 11

对应代码如下:

static u16_t chksum(void *dataptr, u16_t len)//只演示checksum累加的过程
{
  u32_t acc;
  u16_t src;
  u8_t *octetptr;
 
  acc = 0;
  octetptr = (u8_t*)dataptr;
  while (len > 1) {
    src = (*octetptr) << 8;
    octetptr++;
    src |= (*octetptr); //补足两个字节长度
    octetptr++;
    acc += src;
    len -= 2;
  }
  if (len > 0) {
    src = (*octetptr) << 8;
    acc += src;
  }
 
  acc = (acc >> 16) + (acc & 0x0000ffffUL);
  if ((acc & 0xffff0000UL) != 0) {
    acc = (acc >> 16) + (acc & 0x0000ffffUL);
  }
 
  src = (u16_t)acc;
  return ~src;//取反
}

UDP校验和原理

UDP校验数据范围

范围:UDP伪首部(12字节) + UDP首部(8字节) + UDP负载数据

image.png
详情参考网络编程(六)UDP详解

接收方和发送方都遵守该约定。

发送方UDP校验和计算

1、填充伪首部。
2、UDP首部校验和清零。
3、校验数据按照校验和原理计算出校验和。
4、填充校验和至UDP首部校验和字段。

接收方UDP校验和验证

1、接收方接收UDP数据报文(含UDP头部)。
2、填充伪首部。
3、校验数据按照校验和原理校验,满足累加和为0xffff,校验成功。

思考:为什么发送方校验数据(UDP首部校验和)为0,而接收方校验数据(UDP首部校验和)已填充校验和,双方校验数据不一样,不会出错吗?

其实接收方是把计算累加和和校验和验证两个步骤合成了一个步骤,可以理解为接收方先计算校验数据(UDP首部校验和为0)的累加和,再把累加和UDP校验和相加。

image.png

如上图,发送时UDP校验和计算
1)填充伪首部,1byte为8bit,即2byte为16bit,按照规则,伪首部12byte每行为4byte,即每行继续拆分为两部分,拆分为153.19,即153和19表示为16进制为10011001 00010011 。以此类推,可以推导出上图所示数据
2)校验和为0无需清除
3)求和为10010110 11101101 刚好是16bit,无需循环,直接求反,即校验和为01101001 00010010

相关文章

网友评论

      本文标题:Checksum算法(累加校验和)

      本文链接:https://www.haomeiwen.com/subject/wzxnfjtx.html