精华内容
下载资源
问答
  • Modbus-RTU通讯协议CRC校验的计算步骤及算法代码

    万次阅读 多人点赞 2018-09-17 19:01:35
    在CRC计算时只用8个数据位,起始位及停止位,如有奇偶校验位也包括奇偶校验位,都不参与CRC计算。 CRC计算方法是: 1、 预置1个16位寄存器为十六进制FFFF(全1),此寄存器为CRC寄存器 2、 把第一个8位二进制...

    在CRC计算时只用8个数据位,起始位及停止位,如有奇偶校验位也包括奇偶校验位,都不参与CRC计算。

    CRC计算方法是:

    1、 预置1个16位的寄存器为十六进制FFFF(全1),此寄存器为CRC寄存器

    2、 把第一个8位二进制数据(即通讯信息帧的第一个字节)与16位的CRC寄存器的低八位相异或,吧结果存放于CRC寄存器。

    3、 把CRC寄存器的内容右移一位(朝低位)用0填补最高位,并检测右移后的移出位。

    4、 如果移出位为零,则重复第三步(再次右移一位);如果移出位为1,CRC寄存器与多项式A001进行异或。

    5、 重复步骤3和4,直到右移8次,这样整个8位数据全部进行了处理。

    6、 重复步骤2和5,进行通讯信息帧下一个字节的处理。

    7、 将该通讯信息帧所有字节按上述步骤计算完成后,得到的16位CRC寄存器的高、低字节进行交换

    8、 最后得到的CRC寄存器内容即为:CRC校验码。

    Uint16 GetCrcData(Uint8 *buffer, Uint32 len)
    {
    	Uint16 wcrc = 0XFFFF;//16位crc寄存器预置
    	Uint8 temp;
    	Uint32 i = 0, j = 0;//计数
    	for (i = 0; i < len; i++)//循环计算每个数据
    	{
    		temp = *buffer & 0X00FF;//将八位数据与crc寄存器亦或
    		buffer++;//指针地址增加,指向下个数据
    		wcrc ^= temp;//将数据存入crc寄存器
    		for (j = 0; j < 8; j++)//循环计算数据的
    		{
    			if (wcrc & 0X0001)//判断右移出的是不是1,如果是1则与多项式进行异或。
    			{
    				wcrc >>= 1;//先将数据右移一位
    				wcrc ^= 0XA001;//与上面的多项式进行异或
    			}
    			else//如果不是1,则直接移出
    			{
    				wcrc >>= 1;//直接移出
    			}
    		}
    	}
    	Uint8 CRC_L;//定义数组
    	Uint8 CRC_H;
    	CRC_L = wcrc&0xff;//crc的低八位
    	CRC_H = wcrc >> 8;//crc的高八位
    	return ((CRC_L << 8) | CRC_H);
    }
    

    其中Uint8的数据类型是unsigned char,Uint16的数据类型是unsigned short,Uint32的数据类型是unsigned int。
    感觉有用的小伙伴点个赞再走呗,哈哈!。
    这里写图片描述

    展开全文
  • EAN码校验位的计算方法

    千次阅读 2005-11-14 18:08:00
    /** EAN码校验位计算方法 从代码位置序号2开始,所有偶数位的数字代码求和为a。 将上步中的a乘以3为a。 从代码位置序号3开始,所有奇数位的数字代码求和为b。 将a和b相加为c。 取c的个位数d。 用10减去d即为校验位...

    /**
       EAN码校验位的计算方法
       从代码位置序号2开始,所有偶数位的数字代码求和为a。
       将上步中的a乘以3为a。
       从代码位置序号3开始,所有奇数位的数字代码求和为b。
       将a和b相加为c。
       取c的个位数d。
       用10减去d即为校验位数值。

       例:234235654652的校验码的计算如下表:

       数据码 校验码
       代码位置序号 13 12 11 10 9 8 7 6 5 4 3 2 1
       数字码 2 3 4 2 3 5 5 5 4 6 5 2 ?
       偶数位     3 + 2 + 5 + 5 + 6 + 2
       奇数位 2 + 4 + 3 + 5 + 4 + 5

       步骤1:3+2+5+5+6+2=23
       步骤2:23*3=69
       步骤3:2+4+3+5+4+5=23
       步骤4:69+23=92
       步骤5:10-2=8
       步骤6:校验码为 8


       数据码 校验码
       代码位置序号 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1
       数字码 2 0 0 0 0 0 5 0 0 2 2 0 0 0 1 4 7 ?
       偶数位 2 + 0 + 0 + 5 + 0 + 2 + 0 + 1 + 7
       奇数位      0 + 0 + 0 + 0 + 2 + 0 + 0 + 4

       步骤1:2+0+0+5+0+2+0+1+7=17
       步骤2:17*3=51
       步骤3:0+0+0+0+2+0+0+4=6
       步骤4:51+6=57
       步骤5:10-7=3
       步骤6:校验码为 3

      */ 
      

    /// <summary>
      /// EAN码校验位的计算
      /// </summary>
      /// <param name="szCode"></param>
      /// <returns></returns>
      private bool GetVerifyBit(ref string szCode)
      {
       int nNum1 = 0;
       int nNum2 = 0;
       int nNum3 = 0;
       int szLen = 0; 
       if ( szCode == null )
        return false;
       
       szLen = szCode.Length;    
       if(szLen <=12 || szLen >= 17)
            return true;
       for ( int i=0; i<szLen; i++)
       {   

        if ( i%2 == 0 )
        {
         nNum2 += int.Parse(szCode[i].ToString()); //偶数     
        }
        else
        {
         nNum1 += int.Parse(szCode[i].ToString()); //奇数     
        }
       }
       nNum3 = (Operator.DiscountLabelBarLength % 2 ==0) ? nNum1 + nNum2 * 3 : nNum1 * 3 + nNum2 ; 
       
       int t ;
       if(nNum3%10>0) t= 10- (nNum3 % 10) ;
       else t=0;
       szCode+=t;

       return true
      }

        

    /// <summary>
      /// EAN码校验位的计算
      /// </summary>
      /// <param name="szCode"></param>
      /// <returns></returns>
      private bool GetVerifyBit(ref string szCode)
      {
       int nNum1 = 0;
       int nNum2 = 0;
       int nNum3 = 0;
       int szLen = 0; 
       if ( szCode == null )
        return false;
       
       szLen = szCode.Length;    
       if(szLen <=12 || szLen >= 17)
            return true;
       for ( int i=0; i<szLen; i++)
       {   

        if ( i%2 == 0 )
        {
         nNum2 += int.Parse(szCode[i].ToString()); //偶数     
        }
        else
        {
         nNum1 += int.Parse(szCode[i].ToString()); //奇数     
        }
       }
       nNum3 = (Operator.DiscountLabelBarLength % 2 ==0) ? nNum1 + nNum2 * 3 : nNum1 * 3 + nNum2 ; 
       
       int t ;
       if(nNum3%10>0) t= 10- (nNum3 % 10) ;
       else t=0;
       szCode+=t;

       return true
      }

        

        

    如果再精简些应该直接用数组类型来实现,这样就不用使用string了.代码中的细节部分不是效率最高写法.盖于本人学历尚浅,对char等类型掌握的还不熟.所以就用一堆的转型来解决了.

    代码用c#写成,相信学java人士也能看懂吧 呵呵

    前几天上传得代码有问题居然没人发现,汗,还是自己改过来吧...现在已经改完了,不知道会不会有其他得问题了,欢迎批评啊

    展开全文
  • 先上代码 #include <fstream> #include <iostream> #include <stdlib.h>...using namespace std;...//存放数据数组 ...//变量记录数据1个数 ifstream inFile("data.txt");//...
    • 先上代码
    #include <fstream>
    #include <iostream>
    #include <stdlib.h>
    using namespace std;
    int main(){
    	int data[10];//存放数据的数组
    	int count=0;//变量记录数据中1的个数
    	ifstream inFile("data.txt");//读取数据文本
        if(!inFile)
               { cerr<<"无法打开"<<endl;exit(1);}
        for(int i=0;i<10;i++){
    		inFile>>data[i];
    		if(data[i]==1){//数据中有1则count+1
    			count=count+1;
    		}
    	}
    	cout<<"原始数据为:"<<endl;
    	for(int j=0;j<10;j++){
    		cout<<data[j];//读出原始数据
    		break;
    	}
    	cout<<endl;
    	if(count%2==1){
    		cout<<"偶校验校验位为 0"<<endl;
    		cout<<"奇校验位验位为 1"<<endl;
    		}	
    	if(count%2==0){
    		cout<<"偶校验校验位为 1"<<endl;
    		cout<<"奇校验位验位为 0"<<endl;
    		}	
    }
    

    我们需要在.cpp文件目录中
    构建一个data.txt文档存放十位01二进制串

    • 效果如图

    C语言奇偶检测校验位

    展开全文
  • 文章目录前言题目——计算文件16位校验和实验原理分析与代码实现思路代码实验结果 前言 此题来自于计算机网络实验一道题,此题思路理解不难,实现难点在于进制转换。 知识点:运算、掩码运算、文件读写 ...

    前言

    此题来自于计算机网络实验的一道题,此题思路理解不难,实现的难点在于进制的转换。
    知识点:位运算、掩码运算、文件读写

    题目——计算文件的16位校验和

    编写一个计算机程序用来计算一个文件的16位校验和。最快速的方法是用一个32位的整数来存放这个和。记住要处理进位(例如,超过16位的那些位),把它们加到校验和中。
    要求:
    1)以命令行形式运行:check_sum infile
    其中check_sum为程序名,infile为输入数据文件名。
    2)输出:数据文件的效验和
    附:校验和(checksum)
    参见RFC1071 - Computing the Internet checksum
     原理: 把要发送的数据看成16比特的二进制整数序列,并计算他们的和。若数据字节长度为奇数,则在数据尾部补一个字节的0以凑成偶数。
     例子: 16位校验和计算,下图表明一个小的字符串的16位效验和的计算。
    为了计算效验和,发送计算机把每对字符当成16位整数处理并计算校验和。如果校验和大于16位,那么把进位一起加到最后的校验和中。
    在这里插入图片描述

    实验原理分析与代码实现思路

    ①首先,生成一个名为test.txt的文件,并写入一段字符串"Hello World!"
    ②计算校验和
    a)字符读取,并强制转化成ASCII码对应的序号。每次读取两个字符,直到文件结尾。当字符数量为奇数时,第二个字符为0。
    b)采用位运算的方法,两个字符拼接成组。第一个字符的数值左移8位,相当于乘以2的8次方,与第二个字符的数值相加,得到的结果几位两个字母拼接之后的十进制数值,后面直接通过每组计算的数值进行计算即可。
    c)十进制求和。将每一组的十进制数值相加,得到一个十进制整数checksum32 (int类型为32位,不用考虑求和后溢出问题)
    d)进位处理与进制转换。通过掩码方法(位运算)可以将十进制数转换为二进制数,并加32位二进制分成高16位和低16位,再分别转成两个十进制数(对应的二进制16位)并相加得到真正的校验和checksum16。最后,通过位运算将其转换成16进制表示即可。

    代码

    #include <fstream>
    #include <iostream>
    using namespace std;
    
    #define File "test.txt"
    
    void writefile() {
    	ofstream file;
    	file.open(File);
    	file << "Hello World!";
    	file.close();
    }
    
    void checksum(const char* filename) {
    	int checksum32 = 0;
    	fstream file;
    	file.open(File, ios::in);
    	printf("读取的文件数据为:");
    	while (!file.eof()) {
    		char a = file.get();
    		printf("%c", a);
    		//printf("%d ", a);
    		if (a == -1) break;  //到达文件结尾
    		int b = a;
    		//printf("%d ", b << 8);
    		int hex;
    		int d;
    		char c = file.get();
    		printf("%c", c);
    		//printf("%d ", c);
    		if (c == -1) {  //奇数个字符
    			d = 0;
    		}
    		else {  //偶数个字符
    			d = c;
    		}
    		hex = (b << 8) + d;  //注意加括号!!!
    		checksum32 += hex;
    		//printf("%d\n", hex);
    	}
    	printf("\n\n");
    	printf("每两个字母为一组,组成16位。将每一组的10进制数求和,得到结果如下:\n");
    	printf("32位校验和的10进制为:%d\n", checksum32);
    	//通过掩码转化为2进制
    	printf("32位校验和的2进制数为:");
    	for (int i = 0; i < 32; ++i) {
    		if (i == 16) printf(" ");
    		int binaryKey = checksum32 & (1 << 31 - i);
    		if (binaryKey != 0) binaryKey = 1;
    		printf("%d", binaryKey);
    	}
    	int left;  //进位
    	int right;
    	left = checksum32 & (0xffff0000);
    	left = left >> 16;
    	right = checksum32 & (0x0000ffff);
    	printf("\n\n");
    	printf("将32位二进制拆分成高16位进位数,低16位非进位数,得到结果如下:\n");
    	//printf("\nleft=%d  ", left);
    	//printf("right=%d\n", right);
    	//printf("\n");
    	printf("高16位的二进制数为:");
    	for (int i = 0; i < 16; ++i) {
    		int binaryKey = left & (1 << 15 - i);
    		if (binaryKey != 0) binaryKey = 1;
    		printf("%d", binaryKey);
    	}
    	printf("\n");
    	printf("低16位的二进制数为:");
    	for (int i = 0; i < 16; ++i) {
    		int binaryKey = right & (1 << 15 - i);
    		if (binaryKey != 0) binaryKey = 1;
    		printf("%d", binaryKey);
    	}
    	printf("\n\n");
    	printf("将高位和地位的16进制相加,得到如下结果:\n");
    	//printf("\n");
    	int checksum16 = left + right;
    	printf("16位校验和的10进制为:%d\n", checksum16);
    	printf("16位校验和的2进制为:");
    	for (int i = 0; i < 16; ++i) {
    		int binaryKey = checksum16 & (1 << 15 - i);
    		if (binaryKey != 0) binaryKey = 1;
    		printf("%d", binaryKey);
    	}
    	printf("\n");
    	//转化为16进制为:
    	char checksumHex[5];
    	int hex = 0;
    	for (int i = 0; i <16; ++i) {
    		hex = hex + (checksum16&(1 << (15 - i)));
    		if ((i + 1) % 4 == 0) {
    			hex = hex >> (15 - i);  //每四位的8421之和
    			//printf("测试:%d\n", hex);
    			if (hex < 10) checksumHex[i / 4] = hex + '0';
    			else checksumHex[i / 4] = hex - 10 + 'A';
    			hex = 0;
    		}
    	}
    	checksumHex[4] = '\0';
    	printf("\n16位校验和的16进制为:");
    	printf("%s\n", checksumHex);
    }
    
    int main()
    {
    	//writefile();
    	//char*filename;
    	char*command;
    	char*filename;
    	command = new char[20];
    	filename = new char[20];
    	printf("请输入要执行的命令和处理的文件名(用空格分开):\n");
    	cin >> command >> filename;
    	//printf("输入的命令是:%s\n", command);
    	if (!strcmp(command, "check_sum")) {  //字符串相等返回0
    		
    		//printf("输入的文件名为:%s\n", filename);
    		try {
    			fstream file;
    			file.open(filename, ios::in);
    			printf("读取文件成功!\n");
    		}
    		catch (...) {
    			printf("文件打开失败,请确认文件是否存在!\n");
    		}
    		checksum(filename);
    	}
    	else {
    		printf("输入命令无效!\n");
    	}
    	//checksum(File);
    }
    
    

    实验结果

    文件的字符串采用题目给定的例子,代码最终输出的结果也与题目给定结果相同,验证了算法的正确性。
    在这里插入图片描述

    展开全文
  • 组织机构中校验的计算方法

    千次阅读 2010-04-01 19:09:00
    1.组织机构中校验的计算方法 全国组织机构代码由八位数字(或大写拉丁字母)本体代码和一数字(或大写拉丁字母)校验码组成。校验码按下列公式计算: 8C9=11-MOD(∑Ci×Wi,11) i=1 MOD-表示求余函数;i-表示...
  • 循环冗余校验冗余码的计算

    千次阅读 2019-06-24 22:55:04
    则对应g(x)的代码为: 11001 发送方:发出传输字段为: 10110011010 接收方:使用相同生成码进行校验:接收到字段/生成码(二进制除法),如果能够除尽,则正确 除法没有数学上含义,而是采用计算机模二除法,...
  • 身份证校验计算

    2020-11-12 17:51:01
    《中华人民共和国国家标准GB 11643-1999》有关公民身份号码规定,公民身份号码是特征组合码,由十七数字本体码和一数字校验码组成。 排列顺序从左至右依次为: 六数字地址码 (编码对象常住户口所在县(市...
  • EAN校验的计算方法

    千次阅读 2017-12-26 16:39:29
     EAN码校验位计算方法   从代码位置序号2开始,所有偶数位的数字代码求和为a。   将上步中的a乘以3为a。   从代码位置序号3开始,所有奇数位的数字代码求和为b。   将a和b相加为c。   取c的个位数d。 ...
  • (2)实现上述功能 VB 程序如下,请在划线处填入合适代码。Private SubCommand1_Click()Dim i As Integer,a As Integer, b As Integer, sum As Integer, pos As IntegerDim idCode AsString, result As StringConst ...
  • IP首部校验计算

    2016-10-31 18:06:00
    根据RFC1071文档的计算方法,编写代码实现IP首部校验的计算 计算步骤: 1.首先将IP首部中校验和字段置0 2.将IP首部每16bit进行相加,如果有进位产生,则将进位加到最低。 3.将计算的结果取反即可 1 ...
  • 根据下表找出 R 对应的校验码即为要求身份证号码的校验码C。  R 0 1 2 3 4 5 6 7 8 9 10  C 1 0 X 9 8 7 6 5 4 3 2 由此看出 X 就是 10,罗马数字中的 10 就是X,所以在新标准的身份证号码中可能含有非数字的字母X...
  • 生成车辆车架号(VIN)第9的校验码,也可用于检验你得到的VIN码的正确性。用VBA宏代码写成Excel函数,在一个单元格输入VIN码,像普通的Excel公式拖拽一样,直接拖出其校验码。不用Excel数组公式奇怪操作。 ...
  • 海明码(Hamming Code)是一个可以有多个校验位,具有检测并纠正一位错误代码的纠错码,所以它也仅用于信道特性比较好环境,如以太局域网,因为如果信道特性不好情况下,出现错误通常不是一位。...
  • CRC,全称Cyclic Redundancy Check,中文名称为循环冗余校验,是一种根据网络数据包或计算机文件等数据产生简短固定位数校验一种信道编码技术,主要用来检测或校验数据传输或者保存后可能出现错误。...
  • 校验码按照以下公式计算: C9=11-MOD(∑Ci(i=1→8)×Wi,11) 式: MOD——代表求余函数; i——代表代码字符从左至右位置序号; Ci——代表第i的代码字符值(具体代码字符见附表); C9——代表校验码; ...
  • Python 组织机构代码校验

    千次阅读 2016-08-03 14:59:13
    全国组织机构代码由八位数字(或大写拉丁字母)本体代码和一数字(或大写拉丁字母)校验码组成。校验码按照以下公式计算: ...CiC_{i}——代表第i的代码字符值,代码字符机器处理字符数值见下表:
  • 最近使用PHP开发串口通信业务,在发送485Modbus命令时,基本都要...代码如下:/***crc16计算*传入字符串格式:001624180101*返回值格式:[高8,低8]*/functioncrc16($string){$string=pack('H*',$string);$crc=...
  • 最近使用PHP开发串口通信业务,在发送485Modbus命令时,基本都要...代码如下:/***crc16计算*传入字符串格式:001624180101*返回值格式:[高8,低8]*/functioncrc16($string){$string=pack('H*',$string);$crc=...
  • 目录一、CRC16实现代码二、CRC32编码字符表三、CRC校验手动计算示例四、CRC校验原理五、CRC生成多项式参考一、CRC16实现代码思路:取一个字符(8bit),逐检查该字符,如果为1,crc^crc_mul;同时,如果原本crc...
  • 最近使用PHP开发串口通信业务,在发送485Modbus命令时,基本都要计算CRC16校验码。网上搜索了很多文章,很多都计算的不对。本文记录搜索到正确的计算方法。 代码如下: /** *crc16计算 *传入字符串格式:...
  • 下面的C语言代码片段显示了如何使用逐移位和异或运算来计算Modbus消息CRC。使用消息帧中的每个字节计算CRC,除了包含CRC本身的最后两个字节。一、CRC16校验码的使用 现选择最常用的CRC-16校验,说明它的使用方...
  • 计算机组成原理 存储器的校验

    千次阅读 2020-10-07 22:01:58
    所谓编码最小距离,是指在一种编码系统,任意两组合法代码之间最少二进制位数差异。 举例说明: 编码系统第一组 0 0 0 0 1 0 1 0 1 编码系统第二组 0 0 0 1 1 0 1 1 1 编码系统第三组 0 0 1 1 1 1 1 1 1 编码...
  • 问题大概是输入一个12位的校验码,通过对其偶数(即12位中的第2/4/6/8/10/12)求和并乘以3得到A,奇数求和得到B , 取A,B之和为C,用大于C的最小10的倍数做差得出校验码,输出。 主要搞不清的地方1是这个12位的...
  • ... 同学们一定见过商品条形码吧!商品条形码是一个13位数,它是商品“身份证”.条形码前8是厂商识别代码,接着4是商品项目代码,最后一校验码,校验码是由前12...
  • 通过VB编写上位机与下机通信时,数据之和以及异或校验的编写,其中数据以16进制ASCII编程,在变频器通信和PLC通信中计算代码和有所帮助,希望能够为做工程朋友尽鄙人微薄力量。解压密码:liehuo.net
  • 计算机组成原理之奇偶校验

    千次阅读 2020-03-20 13:03:42
    根据被传输的一组二进制代码的数位中的"1"的个数是奇数或者偶数来进行校验。 其中用奇数的称为奇校验,否则就称为偶校验。 若用奇校验,则当接收端收到这组代码时,校验“1”的个数是否为奇数,从而确定传输代码的...
  • VB通信数据转换,16进制ASC...通过VB编写上位机与下机通信时,数据之和以及异或校验的编写,其中数据以16进制ASCII编程,在变频器通信和PLC通信中计算代码和有所帮助,希望能够为做工程朋友尽鄙人微薄力量。
  • 发送ICMP报文时,必须由程序自己计算校验和,将它填入ICMP头部对应校验的计算方法是: 将数据以字(16)为单位累加到一个双字,如果数据长度为奇数,最后一个字节将被扩展到字,累加结果是一个双...

空空如也

空空如也

1 2 3 4 5 ... 15
收藏数 300
精华内容 120
关键字:

代码中的校验位计算