CRC16位校验_C/C++_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > C/C++ > CRC16位校验

CRC16位校验

 2012/9/8 11:51:02  xiaoliouc  程序员俱乐部  我要评论(0)
  • 摘要:在做项目过程中,对方传输CRC16校验函数是C++代码写的,而自己从串口接收数据用java语言,不得不看懂他们的代码。然后自己用java代码来实现。由于正确帧格式是以#开头,以;结束,中间前19位为传输位,后4位为校验位。形如"#12345678912345678912345;"这样的格式才算正确。像多位,少位的情况直接忽视,因为传输的肯定不正确。而对于这种正确格式,我就需要用他们提供的CRC16位校验函数计算校验码与接收的校验码对比,如果完全相同,ok。传输正确,并把数据解析插入数据库
  • 标签:
   在做项目过程中,对方传输CRC16校验函数是C++代码写的,而自己从串口接收数据用java语言,不得不看懂他们的代码。然后自己用java代码来实现。

    由于正确帧格式是以#开头,以;结束,中间前19位为传输位,后4位为校验位。形如"#12345678912345678912345;"这样的格式才算正确。像多位,少位的情况直接忽视,因为传输的肯定不正确。而对于这种正确格式,我就需要用他们提供的CRC16位校验函数计算校验码与接收的校验码对比,如果完全相同,ok。传输正确,并把数据解析插入数据库。
   
     //计算校验码
u32 CRC_Convert(u8 *toConvert, u16 length)  //后面要根据帧的不同设置不同的长度
{
	u32 crc = 0;
	u8 i;
	u8 *ptr = toConvert + 1;
	
	while(length--)
	{
		for(i = 0x80; i != 0; i = i >> 1)
		{
			if((crc & 0x8000) != 0)
			{
				crc = crc << 1;
				crc = crc ^ 0x11021;
			}
			else
			{
				crc = crc << 1;
			}
			if((*ptr & i) != 0)
			{
				crc = crc ^ 0x1021;// 0x10000 ^ 0x11021
			}
		}
		ptr++;
	}
	return crc;
}

//提取校验码
u16 HexString_To_UnsignedShort(u8 hexString[4])
{
	u8 *ptr = hexString;  //根据帧类型判断要加几
	u16 crc = 0;
	u16 i;	

	//将校验位的字符转换为相应的十六进制数
	for(i = 0; i < 4; i++)
	{
		crc <<= 4;
		if(*(ptr + i) >= 'A' && *(ptr + i) <= 'F')
		{
			crc |= *(ptr + i) - 'A' + 10;
		}
		else if(*(ptr + i) >= '0' && *(ptr + i) <= '9')
		{
			crc |= *(ptr + i) - '0';
		}
		else if(*(ptr + i) >= 'a' && *(ptr + i) <= 'f')
		{
			crc |= *(ptr + i) - 'a' + 10;
		}
		else
		{
			return 0;
		}
	}

	return crc;	
}



上面的C++代码实现,我改写的java代码如下。


public class testCRC {
	public static void main(String args[]){
		String oldStr ="#12345678912345678912345;";
		String str = oldStr.substring(1,20);
		String valStr = oldStr.substring(20,24);
		System.out.println(valStr);		
		//System.out.println(str);
		//String str="1234567891234567891";		
		 int aa = CRC_Convert(str,str.length());
//	System.out.println(aa);
	String bb = Integer.toHexString(aa);
//	System.out.printf("%x",aa);
	System.out.println(bb);
	
if(bb.equals(valStr))
{
	System.out.println("传输正确");
	}
	}
	
	 public  static  int CRC_Convert(String str, int length)  //后面要根据帧的不同设置不同的长度
	 {	
		 
		 int crc = 0;
		 	int i;
		   char[] ptr = new char[length]; 
		 	for(int k=0;k<length;k++){ 
		 	ptr[k] = str.charAt(k); 
		
	 		for(i = 0x80; i != 0; i = i >> 1)
	 		{
	 			if((crc & 0x8000) != 0)
	 			{
	 				crc = crc << 1;
	 				crc = crc ^ 0x11021;
	 			}
	 			else
	 			{
	 				crc = crc << 1;
	 			}
	 			if((ptr[k] & i) != 0)
	 			{
	 				crc = crc ^ 0x1021;// 0x10000 ^ 0x11021
	 			}
	 
	 	}
	 	}
	 	return crc;
	 }
	

}



总结:在CRC16位校验中,一般都是采用从起始位循环异或右移,直至最后一位结束。
  • 相关文章
发表评论
用户名: 匿名