Checksum算法

转载自:https://blog.csdn.net/zjli321/article/details/74908451

前言: 
在网络中传输数据包,为了保证传输数据的正确性,使用了 
checksum来校验数据是否正确,ip头有自己的checksum,tcp、 
udp也有自己的checksum,分别校验不同部分的数据,ip头的 
checksum用于校验ip头的数据是否正确,tcp的checksum用于校 
验tcp头、tcp数据部分是否正确,udp的checksum用于校验udp 
头、udp数据是否正确。

一、 checksum的计算方法

1、 先将需要计算checksum数据中的checksum设为0; 
2、 计算checksum的数据按2byte划分开来,每2byte组成一个16bit的值,如果最后有单个byte的数据,补一个byte的0组成2byte; 
3、 将所有的16bit值累加到一个32bit的值中; 
4、 将32bit值的高16bit与低16bit相加到一个新的32bit值中,若新的32bit值大于0Xffff, 
再将新值的高16bit与低16bit相加; 
5、 将上一步计算所得的16bit值按位取反,即得到checksum值,存入数据的checksum字段即可

计算例子: 
如计算下面一段数据的checksum,数据为16进制; 
45 00 00 3c 00 00 00 00 40 11 6d 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 0000 c0a8 2bc3 0808 0808 1100 
计算:4500+003c+0000+0000+4011+0000+c0a8+2bc3+0808+0808+1100 = 192C8 
高低16bit相加: 1 + 92C8 = 92C9 
取反: ~92C9 = 6D36 
最后所得数据为:45 00 00 3c 00 00 00 00 40 11 6d 36 c0 a8 2b c3 08 08 08 08 11

    如下为计算checksum的代码段:
  • 1
  • 2
static u16_t chksum(void *dataptr, u16_t len)
{
  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;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

二、 IP TCP UDP计算checksum包含的数据

1、 IP头的checksum 
只使用ip头数据进行计算 
2、 TCP/udp的checksum 
Tcp/udp的Checksum计算的数据,除了包含tcp/udp头及tcp数据外,还需要增加一个伪tcp/udp头,伪tcp/udp头结构如下:

struct 
{
    unsigned long saddr; //源地址
    unsigned long daddr; //目的地址
    char mbz;//置空
    char ptcl; //协议类型
    unsigned short tcpl; //TCP长度
}psd_header;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

这样,tcp/udp的checksum计算数据如下: 
Tcp:伪头部+tcp头部+tcp数据 
Udp:伪头部+udp头部+udp数据


  • 0
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值