增量式修改报文校验和

计算方法

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);
}

输出

参考资料

https://blog.csdn.net/force_eagle/article/details/38546009

posted on 2024-03-31 14:48  王景迁  阅读(45)  评论(0编辑  收藏  举报

导航