增量式修改报文校验和
计算方法
HC:旧检验和
HC':新检验和
m:16位修改前值
m':16位修改后值
RFC1624修改某个16位域校验和
HC' = HC - ~m - m'
测试验证
#include <stdio.h>
#define data_len 26
unsigned short get_checksum(unsigned short *data)
{
unsigned long sum = 0;
int i;
for (i = 0; i < data_len; i++)
{
sum += *data;
data++;
sum = (sum >> 16) + (sum & 0xffff);
}
return ~sum;
}
unsigned short csum_incremental_update(unsigned short old_csum, unsigned short old_field, unsigned short new_field)
{
unsigned long csum = old_csum - (~old_field & 0xFFFF) - new_field;
csum = (csum >> 16) + (csum & 0xFFFF);
csum += (csum >> 16);
return csum;
}
void recal_csum(unsigned short *old_data, unsigned short * new_data, unsigned short old_field, unsigned short new_field)
{
unsigned short old_sum = get_checksum(old_data);
printf("旧校验和:%x,增量计算的新校验和:%x,全量计算的新校验和:%x\n", old_sum, csum_incremental_update(old_sum, old_field, new_field), get_checksum(new_data));
}
int main()
{
// 修改第1个16位
unsigned short old_data1[data_len] = {0x0a10, 0x0009, 0xac12, 0x0004, 0x0006, 0x0028, 0xa33e, 0x19f2, 0xab45, 0xfbdc, 0x0000, 0x0000, 0xa002, 0x6a40, 0x0000, 0x0000, 0x0204, 0x0550, 0x0402, 0x080a, 0x04c6, 0xda8a, 0x0000, 0x0000, 0x0103, 0x0307};
unsigned short new_data1[data_len] = {0x0a13, 0x0009, 0xac12, 0x0004, 0x0006, 0x0028, 0xa33e, 0x19f2, 0xab45, 0xfbdc, 0x0000, 0x0000, 0xa002, 0x6a40, 0x0000, 0x0000, 0x0204, 0x0550, 0x0402, 0x080a, 0x04c6, 0xda8a, 0x0000, 0x0000, 0x0103, 0x0307};
recal_csum(old_data1, new_data1, 0x0a10, 0x0a13);
// 修改中间1个16位
unsigned short old_data2[data_len] = {0x0a10, 0x0009, 0xac12, 0x0004, 0x0006, 0x0028, 0xa33e, 0x19f2, 0xab45, 0xfbdc, 0x0000, 0x0000, 0xa002, 0x6a40, 0x0000, 0x0000, 0x0204, 0x0550, 0x0402, 0x080a, 0x04c6, 0xda8a, 0x0000, 0x0000, 0x0103, 0x0307};
unsigned short new_data2[data_len] = {0x0a10, 0x0009, 0xac12, 0x0004, 0x0006, 0x0028, 0xa33a, 0x19f2, 0xab45, 0xfbdc, 0x0000, 0x0000, 0xa002, 0x6a40, 0x0000, 0x0000, 0x0204, 0x0550, 0x0402, 0x080a, 0x04c6, 0xda8a, 0x0000, 0x0000, 0x0103, 0x0307};
recal_csum(old_data2, new_data2, 0xa33e, 0xa33a);
// 修改最后1个16位
unsigned short old_data3[data_len] = {0x0a10, 0x0009, 0xac12, 0x0004, 0x0006, 0x0028, 0xa33e, 0x19f2, 0xab45, 0xfbdc, 0x0000, 0x0000, 0xa002, 0x6a40, 0x0000, 0x0000, 0x0204, 0x0550, 0x0402, 0x080a, 0x04c6, 0xda8a, 0x0000, 0x0000, 0x0103, 0x0307};
unsigned short new_data3[data_len] = {0x0a10, 0x0009, 0xac12, 0x0004, 0x0006, 0x0028, 0xa33e, 0x19f2, 0xab45, 0xfbdc, 0x0000, 0x0000, 0xa002, 0x6a40, 0x0000, 0x0000, 0x0204, 0x0550, 0x0402, 0x080a, 0x04c6, 0xda8a, 0x0000, 0x0000, 0x0103, 0x0309};
recal_csum(old_data3, new_data3, 0x0307, 0x0309);
}
输出

浙公网安备 33010602011771号