-
2022-03-26 11:02:28更多相关内容
-
数据发送与接收校验(校验和)_数据校验之校验和_
2021-10-02 10:28:19这是校验数据的一种方式,即校验和方式,可实现数据发送的完整性验证 -
labview校验和与累加和.vi
2020-09-07 23:42:59研究与实战了很久的,发现非常好用的labview校验和,累加和既可以转成16进制单字节又可以转成双字节、也可以四字节类型。下载可以直接调用。 -
NMEA校验和:NMEA校验和计算-matlab开发
2021-05-31 02:33:43NMEA校验和计算功能 -
Labview和校验和与校验
2018-07-10 13:29:46该代码用labview2015编写的和校验和与校验代码,可在项目中直接拿来使用 -
checksum校验和计算工具
2019-09-17 11:52:20checksum校验和计算工具,16进制校验和计算工具,简单实用。 -
16进制校验和软件
2017-11-25 10:17:34最近工作需要,对16进制的数据计算校验和比较多,最关键是还要对BIN文件进行做校验和,无奈之下,写了一个小软件,希望对大家都有帮助,所以分享一下 1.支持单个输入数据计算 1.支持单个输入数据计算 2.支持文件读取... -
校验和计算工具
2019-01-17 14:42:03校验和计算工具 -
校验和计算工具CheckTool
2018-05-08 21:11:11校验和计算工具CheckTool,用于计算数据的校验和,方便和高效 -
异或校验和计算工具
2017-11-23 15:43:34异或校验和工具,用于计算十六进制数据的异或校验和。 -
UDP校验和计算工具
2016-11-03 13:18:04使用Java开发的UDP校验和,将完整的UDP报文黏贴进去,计算出对应的UDP校验和 -
校验和计算器
2014-10-15 09:47:11用bcb开发的一个计算校验和的小工具,可以计算累加校验和,异或校验和,异或减1校验和 -
16位反码求和校验和生成小工具
2017-11-14 09:52:43反码求和校验和生成小工具 ,输入数据请16进制输入,空格间隔,源码请自行reflector,未做保护 -
java校验和算法
2015-01-20 14:17:22由于需要和蓝牙通讯,协议需要用到校验和,找了很久才找到,给大家共享。java校验和算法绝对可以用。 -
校验和CheckSum获取工具
2014-11-22 23:27:34在通讯技术开发过程中往往需要用到校验和,调试过程中需要计算校验和正确与否?用此工具很方便计算出校验和。 使用说明:在输入文本框中以十六进制输入一串需要计算的数据(以空格分开,不需要0x开头),如输入: 15 ... -
校验和计算
2013-12-03 14:11:04校验和计算,输入需要校验的内容,点击生成,即可生成校验和。 -
IntelHEX校验和计算工具
2015-11-16 15:20:29IntelHEX校验和计算工具 快速的对IntelHEX 格式中的数据进行校验计算 -
vb程序计算校验和
2013-04-13 14:10:27利用vb程序,来计算校验和.输入十六进制字符串,可以得到校验和和一共几个字节。非常方便好用。程序简洁明了。 -
计算校验和的小工具(很实用)
2014-01-11 17:59:35计算校验和的小工具,支持16进制字符串的输入,程序对输入的数据进校验和的计算,方便实际开发中的测试工作。 -
C语言实现网络校验和
2012-10-20 19:39:20C语言实现网络校验和。自己亲自写的,经实验正确。 -
UDP校验和算法
2012-10-28 13:59:05UDP校验和算法,给出了UDP校验和算法的C语言程序。 -
intel hex 校验和计算工具
2012-07-13 12:43:43很多单片机的生成镜像都是Intel hex 格式的,此工具是用来计算行尾的校验和的,只要将一行的数据域(:和结尾校验字节除外)复制到工具中,就能计算出其校验和, 对于要修改hex镜像的数据来说,有了这工具就可以方便... -
串口实现编码数据的收发,带CRC校验,求和校验和奇偶校验
2015-09-07 14:19:50发送端通过液晶触摸屏输入字符,然后编写协议发送,采用4.3寸液晶 接收端将接收到的数据解码,然后将有效字符显示在液晶上,采用2.8寸液晶 接收无误码,使用于各种数字无线收发的应用 -
校验和小工具(求和、异或、CRC)
2014-01-03 21:08:57包含C#源代码,可以计算求和、异或、CRC三种校验和 -
udp校验和计算
2012-12-27 09:49:26udp校验和,基于wireshark的TCP和UDP报文分析 -
VB6.0写的计算CRC校验和的小程序
2014-12-15 13:45:14VB6.0写的计算CRC校验和的小程序,能够计算串口发送数据的校验和(CRC)和异或校验和。经过编译后能够显示为Win7的界面效果。 -
累加校验和CRC16校验计算器
2013-01-07 14:15:55累加校验和CRC16校验计算器,对输入控制的不好,重新输入建议清空后重新输入 -
关于checksum校验和算法
2021-03-05 19:56:23校验和覆盖的内容: IP校验和:IP首部。 ICMP校验和:ICMP首部+ICMP数据; UDP、TCP校验和:首部+数据+12个字节伪首部(源IP地址、目的IP地址、协议、TCP/UDP包长)。 计算校验和的步骤: [1]把校验和字段设置为0。 [2...今天复习计网的时候看到了UDP头部有差错校验,其中的checksum算法没理的太清楚,索性写一篇博客,顺便回顾一下其他的。
校验和覆盖的内容:
IP校验和:IP首部。
ICMP校验和:ICMP首部+ICMP数据;
UDP、TCP校验和:首部+数据+12个字节伪首部(源IP地址、目的IP地址、协议、TCP/UDP包长)。计算校验和的步骤:
[1]把校验和字段设置为0。
[2]把需要校验的数据看成以16位为单位的数字组成,依次进行二进制反码求和。
[3]把得到的结果存入校验和字段中。
另外UDP、TCP数据报的长度可以为奇数字节,因为计算时是16位为单位,所以此时计算校验和时需要在最后增加一个填充字节0(只是计算校验和用,不发送出去)。接收端校验校验和步骤:
把需要校验的内容(包括校验和字段)看成以16位为单位的数字,依次进行二进制反码求和,如果结果是0表示正确,否则表示错误。
二进制反码求和步骤:
[1]二进制反码求和,就是先把这两个数取反,然后求和,如果最高位有进位,则向低位进1。
[2]另外,先取反后相加与先相加后取反,得到的结果是一样的。因此实现代码都是先相加,最后再取反。
下面我们来写个栗子
以4bit(计算方便一点,和16bit是一样的)做检验和来验证。
假设原始数据为 1100 1010 | 0000(校验位)(初始化为0000)
那么把他们按照4bit一组进行按位取反相加。 1100 取反0011 , 1010 取反是0101,校验位的计算就是 0011加上0101 是1000,填入到校验位上
于是发送的数据就是
1100 1010 | 1000
收到数据后同样进行按位取反相加。0011+0101+0111 =1111;全为1表示正确 。 等于是 自己加上自己的取反, 那么 结果肯定应该是全1 。如果传输正确的话。更多思考
至于我一直百思不解的 那个数据报里面那么多数据加起来肯定是每个位都是1这个问题
我们来考虑一种极端情况:
0000 0000
它的校验和是1111
如果最高位需要进位 那么补到最低位上(回卷)
发送过去的 0000 0000 1111 加起来就是1111
当然 如果后面再加个不是0000 比如1010
1010按位取反是0101
加上去那么校验和是0101
发送过去的数据是0000 0000 1010 | 0101
加起来的和还是1111
感觉checksum这个算法设计的太妙了在实际使用过程中 先把需要校验的数据加起来 然后取反码,这样的效果是一样的,而且还减少了计算量
NOTE:
这里是按位取反 不是反码原码 反码 补码
在学习原码, 反码和补码之前, 需要先了解机器数和真值的概念.
机器数和真值
机器数
一个数在计算机中的二进制表示形式, 叫做这个数的机器数。机器数是带符号的,在计算机用一个数的最高位存放符号, 正数为0, 负数为1.
比如,十进制中的数 +3 ,计算机字长为8位,转换成二进制就是00000011。如果是 -3 ,就是 10000011 。
那么,这里的 00000011 和 10000011 就是机器数。
真值
因为第一位是符号位,所以机器数的形式值就不等于真正的数值。例如上面的有符号数 10000011,其最高位1代表负,其真正数值是 -3 而不是形式值131(10000011转换成十进制等于131)。所以,为区别起见,将带符号位的机器数对应的真正数值称为机器数的真值。
例:0000 0001的真值 = +000 0001 = +1,1000 0001的真值 = –000 0001 = –1
原码, 反码, 补码的基础概念和计算方法.
在探求为何机器要使用补码之前, 让我们先了解原码, 反码和补码的概念.对于一个数, 计算机要使用一定的编码方式进行存储. 原码, 反码, 补码是机器存储一个具体数字的编码方式.
原码
原码就是符号位加上真值的绝对值, 即用第一位表示符号, 其余位表示值. 比如如果是8位二进制:
[+1]原 = 0000 0001
[-1]原 = 1000 0001
第一位是符号位. 因为第一位是符号位, 所以8位二进制数的取值范围就是:
[1111 1111 , 0111 1111]
即
[-127 , 127]
原码是人脑最容易理解和计算的表示方式.
反码
反码的表示方法是:
正数的反码是其本身
负数的反码是在其原码的基础上, 符号位不变,其余各个位取反.
[+1] = [00000001]原 = [00000001]反
[-1] = [10000001]原 = [11111110]反
可见如果一个反码表示的是负数, 人脑无法直观的看出来它的数值. 通常要将其转换成原码再计算.
补码
补码的表示方法是:
正数的补码就是其本身
负数的补码是在其原码的基础上, 符号位不变, 其余各位取反, 最后+1. (即在反码的基础上+1)
[+1] = [00000001]原 = [00000001]反 = [00000001]补
[-1] = [10000001]原 = [11111110]反 = [11111111]补
对于负数, 补码表示方式也是人脑无法直观看出其数值的. 通常也需要转换成原码在计算其数值.
为何要使用原码, 反码和补码
在开始深入学习前, 我的学习建议是先"死记硬背"上面的原码, 反码和补码的表示方式以及计算方法.
现在我们知道了计算机可以有三种编码方式表示一个数. 对于正数因为三种编码方式的结果都相同:
[+1] = [00000001]原 = [00000001]反 = [00000001]补
所以不需要过多解释. 但是对于负数:
[-1] = [10000001]原 = [11111110]反 = [11111111]补
可见原码, 反码和补码是完全不同的. 既然原码才是被人脑直接识别并用于计算表示方式, 为何还会有反码和补码呢?
首先, 因为人脑可以知道第一位是符号位, 在计算的时候我们会根据符号位, 选择对真值区域的加减. (真值的概念在本文最开头). 但是对于计算机, 加减乘数已经是最基础的运算, 要设计的尽量简单. 计算机辨别"符号位"显然会让计算机的基础电路设计变得十分复杂! 于是人们想出了将符号位也参与运算的方法. 我们知道, 根据运算法则减去一个正数等于加上一个负数, 即: 1-1 = 1 + (-1) = 0 , 所以机器可以只有加法而没有减法, 这样计算机运算的设计就更简单了.
于是人们开始探索 将符号位参与运算, 并且只保留加法的方法. 首先来看原码:
计算十进制的表达式: 1-1=0
1 - 1 = 1 + (-1) = [00000001]原 + [10000001]原 = [10000010]原 = -2
如果用原码表示, 让符号位也参与计算, 显然对于减法来说, 结果是不正确的.这也就是为何计算机内部不使用原码表示一个数.
为了解决原码做减法的问题, 出现了反码:
计算十进制的表达式: 1-1=0
1 - 1 = 1 + (-1) = [0000 0001]原 + [1000 0001]原= [0000 0001]反 + [1111 1110]反 = [1111 1111]反 = [1000 0000]原 = -0
发现用反码计算减法, 结果的真值部分是正确的. 而唯一的问题其实就出现在"0"这个特殊的数值上. 虽然人们理解上+0和-0是一样的, 但是0带符号是没有任何意义的. 而且会有[0000 0000]原和[1000 0000]原两个编码表示0.
于是补码的出现, 解决了0的符号以及两个编码的问题:
1-1 = 1 + (-1) = [0000 0001]原 + [1000 0001]原 = [0000 0001]补 + [1111 1111]补 = [0000 0000]补=[0000 0000]原
这样0用[0000 0000]表示, 而以前出现问题的-0则不存在了.而且可以用[1000 0000]表示-128:
(-1) + (-127) = [1000 0001]原 + [1111 1111]原 = [1111 1111]补 + [1000 0001]补 = [1000 0000]补
-1-127的结果应该是-128, 在用补码运算的结果中, [1000 0000]补 就是-128. 但是注意因为实际上是使用以前的-0的补码来表示-128, 所以-128并没有原码和反码表示.(对-128的补码表示[1000 0000]补算出来的原码是[0000 0000]原, 这是不正确的)
使用补码, 不仅仅修复了0的符号以及存在两个编码的问题, 而且还能够多表示一个最低数. 这就是为什么8位二进制, 使用原码或反码表示的范围为[-127, +127], 而使用补码表示的范围为[-128, 127].
因为机器使用补码, 所以对于编程中常用到的32位int类型, 可以表示范围是: [-231, 231-1] 因为第一位表示的是符号位.而使用补码表示时又可以多保存一个最小值.
原码, 反码, 补码 再深入
计算机巧妙地把符号位参与运算, 并且将减法变成了加法, 背后蕴含了怎样的数学原理呢?
将钟表想象成是一个1位的12进制数. 如果当前时间是6点, 我希望将时间设置成4点, 需要怎么做呢?我们可以:
-
往回拨2个小时: 6 - 2 = 4
-
往前拨10个小时: (6 + 10) mod 12 = 4
-
往前拨10+12=22个小时: (6+22) mod 12 =4
2,3方法中的mod是指取模操作, 16 mod 12 =4 即用16除以12后的余数是4.
所以钟表往回拨(减法)的结果可以用往前拨(加法)替代!
现在的焦点就落在了如何用一个正数, 来替代一个负数. 上面的例子我们能感觉出来一些端倪, 发现一些规律. 但是数学是严谨的. 不能靠感觉.
首先介绍一个数学中相关的概念: 同余
同余的概念
两个整数a,b,若它们除以整数m所得的余数相等,则称a,b对于模m同余记作 a ≡ b (mod m)
读作 a 与 b 关于模 m 同余。
举例说明:
4 mod 12 = 4
16 mod 12 = 4
28 mod 12 = 4
所以4, 16, 28关于模 12 同余.
负数取模
正数进行mod运算是很简单的. 但是负数呢?下面是关于mod运算的数学定义:
clip_image001
上面是截图, "取下界"符号找不到如何输入(word中粘贴过来后乱码). 下面是使用"L"和"J"替换上图的"取下界"符号:
x mod y = x - y L x / y J
上面公式的意思是:
x mod y等于 x 减去 y 乘上 x与y的商的下界.
以 -3 mod 2 举例:
-3 mod 2
= -3 - 2xL -3/2 J
= -3 - 2xL-1.5J
= -3 - 2x(-2)
= -3 + 4 = 1
所以:
(-2) mod 12 = 12-2=10
(-4) mod 12 = 12-4 = 8
(-5) mod 12 = 12 - 5 = 7
引用
本文引用了以下文章的部分内容
https://blog.csdn.net/zl10086111/article/details/80907428
https://www.cnblogs.com/ne-liqian/p/9804214.html
https://www.cnblogs.com/seasonal/p/10343642.html -
-
异或校验和
2019-11-21 18:11:18异或校验和 异或校验和算法: #include "stdio.h" void main() { int i; //任意10个数值,也可以不是8位 unsigned char data[10]={0x12,0x21,0x1A,0xB1,0xC1,0xEB,0xDF,0xCA,0xF6,0xDD}; unsigned char out;//用于...异或校验和
即BCC校验
异或校验和算法:#include "stdio.h" void main() { int i; //任意10个数值,也可以不是8位 unsigned char data[10]={0x12,0x21,0x1A,0xB1,0xC1,0xEB,0xDF,0xCA,0xF6,0xDD}; unsigned char out;//用于保存异或结果 out=0x00; for (i=0;i<sizeof(data);i++) { out^=data[i]; } printf("原来的校验值:%X\n",out); out^=(data[0]^0xee);//将data[0]改为新数据后计算新校验和的方法 out^=(data[5]^0x20);//将data[5]改为新数据后计算新校验和的方法 printf("修改后校验值:%X\n",out); data[0]=0xee; //采用原始的方法计算新的校验和,和前面的校验和对比是否正确 data[5]=0x20; //采用原始的方法计算新的校验和,和前面的校验和对比是否正确 out=0x00; for (i=0;i<10;i++) { out^=data[i]; } printf("原始方法得出校验值:%X\n",out); }
我是用我手机里的C语言编译器验证的
运行结果如下:
-
网络的校验和
2022-03-19 19:53:00关于反码求和这个事情,IP/ICMP/IGMP/TCP/UDP等协议的[1]校验和算法都是相同的。 为了求网络协议的校验和,需要把报文的二进制按word,也就是2个字节分割,校验和字段填0,尾部为奇数字节则添加一个字节0. 二字节...关于反码求和这个事情,IP/ICMP/IGMP/TCP/UDP等协议的 校验和算法都是相同的。
为了求网络协议的校验和,需要把报文的二进制按word,也就是2个字节分割,校验和字段填0,尾部为奇数字节则添加一个字节0. 二字节求和后取反。
其实这个事情概念上有点误导,让大家以为是所有2个字节都取反码,然后求和,最后再取反放到校验和字段。当然这样就很绕了。
那以此求和取反,当收到报文重新按2字节二进制求和时,因为最终加了取反的校验和,所以最终结果会是binary全1,即0xFFFF。
当然了,比如UDP算校验和时,还需要加个12字节伪首部,但不影响计算过程。
到这里,再讲下计算机原码,反码,补码的问题。
对正数来说,他们三个都是一样对。所以反码在这里看到了点曙光啊。反码不是取反。
对负数来说,除符号位外,其他取反则是其反码。【1】
对负数来说,补码即其反码+1,原码即符号位为1,其他位为正数表示。
好了,那负数的原码/补码,反码有什么用处呢?
其实计算机里面,正数就是他自己来表示,负数就是补码表示。
why?
我们来看下负数的补码:比如-7,即对正数7 binary表示:0,0111 【取反+1】,即:1,1001.
那么【取反+1】是什么?【取反+1】即是通过正数求补码的一个操作。
可以看到0,0111 + 1,1001 = 0,0000
对1,0111(-7)这个原码来说,取反码+1也是其补码:1,1001. 即【1】所述。
所以,反码只是用于负数原码求补码的一个过渡,没有什么实际意义。也可以直接通过正数【取反+1】得到。