计算方法
HC:旧检验和
HC':新检验和
m:16位修改前值
m':16位修改后值
RFC1624修改某个16位域校验和
HC' = HC - ~m - m'
static inline unsigned short csum_incremental_update(unsigned short old_csum, unsigned short old_field, unsigned short new_field)
{
__asm__ __volatile__(
"notw %1; \n"
"subw %1, %0; \n"
"sbbw %2, %0; \n"
"sbbw $0, %0; \n"
:"=r" (old_csum)
:"r"(old_field), "r"(new_field),"0"(old_csum));
return old_csum;
}
测试验证
#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)
{
__asm__ __volatile__(
"notw %1; \n"
"subw %1, %0; \n"
"sbbw %2, %0; \n"
"sbbw $0, %0; \n"
: "=r"(old_csum)
: "r"(old_field), "r"(new_field), "0"(old_csum));
return old_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);
}
输出
参考资料
https://blog.csdn.net/force_eagle/article/details/38546009
标签:short,old,报文,unsigned,0x0000,校验,增量,csum,data From: https://www.cnblogs.com/WJQ2017/p/18106735