Hash算法中的CRC

CRC是通信领域中用于校验数据传输正确性的最常用机制,也是Hash算法的一个典型应用,Hash一般翻译为“散列”,也可直接音译为“哈希”,就是把任意长度的输入(又叫做预映射,pre-image)通过散列算法变换成固定长度的输出,该输出就是散列值。这种转换是一种压缩映射,也就是散列值的空间通常远小于输入空间,不同的输入可能会散列成相同的输出,而不可能从散列值唯一的确定输入值。

关于CRC校验:(16位二进制数),CRC码由发送设备计算,放置于所发送信息帧的尾部。接收信息的设备重新计算所接收信息(除RCR部分)的CRC,比较计算得到的
CRC是否与接收到的CRC相符,如果两者不相符,则认为数据传输出错,如果相符说明数据传输正确。
(1)预1个16位的寄存器为0xFFFF,称此寄存器为CRC寄存器
(2)把分i一个8位二进制数据(即通信信息帧的第一个字节)与16位的CRC寄存器的低8位相异或,把结果存放于CRC寄存器
(3)把CRC寄存器的内容右移一位,用0填补最高位,并检查右移后的移出位。
(4)如果移出位为0,重复(3),如果移出位为1,CRC寄存器与0xA001进行异或
(5)重复(3)(4),直到右移8次,这样整个8位数据就全部进行了处理
(6)重复(2)到(5),进行通信信息帧下一个字节的处理
(7)将该通信信息帧所有字节按上述步骤计算完成后,得到的16位CRC寄存器的高、低位已经交换
(8)最后得到的CRC寄存器内容即为CRC码

程序代码如下:

#include <stdio.h>
unsigned short modbus_crc(unsigned char* p,int len)
{
	unsigned short ret=0xFFFF;
	int i=0;
	int k=0;

	for(i=0;i<len;++i)
	{
		ret^=p[i];
		for(k=0;k<8;++k)
		{
			ret=(ret&0x01)?((ret>>1)^0xA001):(ret>>1);
		}
	}
	ret=((ret&0xFFFF)<<8) | ((ret&0xFFFF)>>8);
	return ret;
}

int main()
{
	unsigned char input[]={0x01,0x04,0x0D,0x28,0x00,0x02,0x01,0x02,0x00,0x53,0x00,0x01};
	unsigned short out=0;
	int i=0;
	int len=sizeof(input);

	out=modbus_crc(input,sizeof(input));
	printf("Input:");
	for(i=0;i<len;i++)
		printf(" 0x%.2X",input[i]);
	printf("\nModbus CRC is: 0x%.4X\n",out);
	return 0;
}

 常见的Hash算法有:MAC,CRC,MD5/MD4,SHA等。

posted @ 2012-06-07 15:45  always on the way  阅读(8488)  评论(0编辑  收藏  举报