首页 > 其他分享 >增量式修改报文校验和

增量式修改报文校验和

时间:2024-03-31 14:55:54浏览次数:25  
标签:short old 报文 unsigned 0x0000 校验 增量 csum data

计算方法

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

相关文章

  • 计算机组成与体系结构--2.2:校验码
    转上一节---2.1数据的表示计算机组成与体系结构-数据的表示http://t.csdnimg.cn/1WUdC2.2:校验码考点1:奇偶校验码1.校验码基础知识码距:任何-种编码都由许多码字构成,任意两个码字之间最少变化的二进制位数就称为数据校验码的码距。例如:用2位二进制表示4种状态,则有4个......
  • CRC校验方法和FPGA实现
    参考:【科普向】谁都能看懂的CRC(循环冗余校验)原理_crc循环冗余校验原理-CSDN博客CRC校验原理和推导过程及Verilog实现(一文讲透)_crcverilog-CSDN博客介绍两个CRC源码生成工具,可生成Verilog和VHDL-niosII爱好者-博客园(cnblogs.com)GeneratorforCRCHDLcode(bues.ch)......
  • 从奇偶校验到ECC:MIPI-CSI2的校验和
    参考:手写MIPI(一):MIPI-CSI-2RAW10笔记_mipicsi-CSDN博客图像处理项目记录-NoNounknow-博客园(cnblogs.com)【通俗易懂的通信】信道编码之——汉明码_汉明编码-CSDN博客MIPI包的结构:MIPI数据包的包头使用ECC来校验数据的传输是否正确。所以解析MIPI数据必须用到ECC。......
  • Springboot做分组校验
    目录分组校验Insert分组Upload分组测试接口测试结果添加测试更新测试顺序校验@GroupSequence自定义分组校验自定义分组表单 CustomSequenceProvider 测试接口测试结果Type类型为A Type类型为B总结:前文提到了做自定义的校验注解,接下来的这篇文章将带领各......
  • 校验码-体系结构-指令-流水线
    校验码码距:就单个编码A:00而言,其码距为1,因为其只需要改变一位就变成另一个编码。在两个编码中,从A码到B码转换所需要改变的位数称为码距,如A:00要转换为B:11,码距为2。一般来说,码距越大,越利于纠错和检错。奇偶校验码:在编码中增加1位校验位来使编码中1的个数为奇数(奇校验)或者偶数......
  • 接收文件流并导出至excel以及对二进制文件流内容的校验
    废话不说上代码consthandleRightDownload=async()=>{axios({method:'post',url:'/my/handleAndDownloadExcel',//请求地址这里写后端的地址,注意加上`/api`以确保最终的请求能被替换掉,/api表示server要替换的前缀'/api'->''data:{......
  • 新增文章参数校验-2024-3-29
    用到validation自定义校验packagecom.di.bigevent.pojo;importcom.di.bigevent.anno.State;importjakarta.validation.constraints.NotEmpty;importjakarta.validation.constraints.NotNull;importjakarta.validation.constraints.Pattern;importlombok.Data;imp......
  • 爬虫-今日头条我的收藏-增量式导入到Elastic Search(四)
    背景:继成功导入输入数据到mongodb,sqlite3之后,发现了一些问题,(写到此处觉得还是有些地方没有去深入的学习可能mongodb已经有解决方案了?):对关键字查询支持不友好,如果要在sql中拆分出不同的关键字sql会比较麻烦。另外排序不友好,如何把最匹配的记录放在最前面?elasticsearch是对搜......
  • elementUI——el-form表单数据校验(包含数组循环)
    一、普通的值类型的数据校验①设置el-form-item的prop值与formdata中定义的key保持一致`②如果rules需要通过el-form统一设置,rules的key定义也与prop保持一致(如果不一致,需要在el-form-item中手动指定)③复杂的校验函数可通过validator单独定义<el-form......
  • S7Comm报文详解
    S7协议是西门子公司为其S7系列PLC(可编程逻辑控制器)通信而设计的一种专用协议。S7协议主要用于西门子PLC之间的通信,以及PLC与其他设备的通信。该协议支持多种通信方式,如MPI(多点接口)、PROFIBUS和IndustrialEthernet等。S7协议的报文结构相对复杂,可分为多个层次。1.简介对比OSI参......