求CRC-8,G(X)=x8 + x5 + x4 + 1源码

ljdone 2005-06-20 11:27:59
如题
...全文
10484 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
cqpp 2005-06-21
  • 打赏
  • 举报
回复
CRC-8,G(X)=x8 + x5 + x4 + 1对应应该为1 0011 0001 吧,0x0131
cqpp 2005-06-21
  • 打赏
  • 举报
回复
#include <stdio.h>

unsigned char crc8_table[256] = {
0x00, 0x31, 0x62, 0x53, 0xc4, 0xf5, 0xa6, 0x97,
0x88, 0xb9, 0xea, 0xdb, 0x4c, 0x7d, 0x2e, 0x1f,
0x21, 0x10, 0x43, 0x72, 0xe5, 0xd4, 0x87, 0xb6,
0xa9, 0x98, 0xcb, 0xfa, 0x6d, 0x5c, 0x0f, 0x3e,
0x73, 0x42, 0x11, 0x20, 0xb7, 0x86, 0xd5, 0xe4,
0xfb, 0xca, 0x99, 0xa8, 0x3f, 0x0e, 0x5d, 0x6c,
0x52, 0x63, 0x30, 0x01, 0x96, 0xa7, 0xf4, 0xc5,
0xda, 0xeb, 0xb8, 0x89, 0x1e, 0x2f, 0x7c, 0x4d,
0xe6, 0xd7, 0x84, 0xb5, 0x22, 0x13, 0x40, 0x71,
0x6e, 0x5f, 0x0c, 0x3d, 0xaa, 0x9b, 0xc8, 0xf9,
0xc7, 0xf6, 0xa5, 0x94, 0x03, 0x32, 0x61, 0x50,
0x4f, 0x7e, 0x2d, 0x1c, 0x8b, 0xba, 0xe9, 0xd8,
0x95, 0xa4, 0xf7, 0xc6, 0x51, 0x60, 0x33, 0x02,
0x1d, 0x2c, 0x7f, 0x4e, 0xd9, 0xe8, 0xbb, 0x8a,
0xb4, 0x85, 0xd6, 0xe7, 0x70, 0x41, 0x12, 0x23,
0x3c, 0x0d, 0x5e, 0x6f, 0xf8, 0xc9, 0x9a, 0xab,
0xcc, 0xfd, 0xae, 0x9f, 0x08, 0x39, 0x6a, 0x5b,
0x44, 0x75, 0x26, 0x17, 0x80, 0xb1, 0xe2, 0xd3,
0xed, 0xdc, 0x8f, 0xbe, 0x29, 0x18, 0x4b, 0x7a,
0x65, 0x54, 0x07, 0x36, 0xa1, 0x90, 0xc3, 0xf2,
0xbf, 0x8e, 0xdd, 0xec, 0x7b, 0x4a, 0x19, 0x28,
0x37, 0x06, 0x55, 0x64, 0xf3, 0xc2, 0x91, 0xa0,
0x9e, 0xaf, 0xfc, 0xcd, 0x5a, 0x6b, 0x38, 0x09,
0x16, 0x27, 0x74, 0x45, 0xd2, 0xe3, 0xb0, 0x81,
0x2a, 0x1b, 0x48, 0x79, 0xee, 0xdf, 0x8c, 0xbd,
0xa2, 0x93, 0xc0, 0xf1, 0x66, 0x57, 0x04, 0x35,
0x0b, 0x3a, 0x69, 0x58, 0xcf, 0xfe, 0xad, 0x9c,
0x83, 0xb2, 0xe1, 0xd0, 0x47, 0x76, 0x25, 0x14,
0x59, 0x68, 0x3b, 0x0a, 0x9d, 0xac, 0xff, 0xce,
0xd1, 0xe0, 0xb3, 0x82, 0x15, 0x24, 0x77, 0x46,
0x78, 0x49, 0x1a, 0x2b, 0xbc, 0x8d, 0xde, 0xef,
0xf0, 0xc1, 0x92, 0xa3, 0x34, 0x05, 0x56, 0x67};

unsigned char get_value( unsigned short crc )
{
unsigned char i = 0;
for(i = 0; i < 9; i++ )
{
if( (crc&0x0100) !=0 )
{
crc*=2;
crc^=0x31;
}
else
{
crc*=2;
}
}

return (unsigned char)crc;
}

void init_tabl()
{
unsigned short i = 0;
for ( i = 0; i < 0x100; i++ )
{
crc8_table[i] = get_value(i);
if ( !(i%8) )
{
printf( "\n" );
}
printf( "0x%.2x, ", crc8_table[i] );
}
}

unsigned char count_crc8( unsigned char* pbuf, int len, unsigned char seed )
{
unsigned char* data = pbuf;
unsigned char crc = seed;
while ( len-- )
{
crc = crc8_table[crc^*(data++)];
}
return crc;
}

void main()
{
unsigned char data[32] = {1,2,3,4,5,6,7,8,9,10};
unsigned char crc_v = 0;
crc_v = count_crc8( data, 31, 0 );
data[31] = crc_v;
crc_v = count_crc8( data, 32, 0 );
}
aSalt 2005-06-21
  • 打赏
  • 举报
回复
两个字`接分`
styleboy 2005-06-21
  • 打赏
  • 举报
回复
一个字`拽`

jixingzhong 2005-06-21
  • 打赏
  • 举报
回复
循环冗余校验

基本原理如果楼住还没有明白,找本计算机网络原理的书来看看,在前面的基础章节中

G(X)=x8 + x5 + x4 + 1(其实8、5、4是在指数上的,1原来是x的0次方,式子的意思是x从8次方到0次方,对应项的系数,组合成一个二进制数。如x8 + x5 + x4 + 1对应 1001 1000  这个二进制数


这个多项式叫做生成多项式(顾名思义,就是生成校验码的多项式)


把要传输的数据视为一个很大的数(2进制),除以生成多项式
(CRC-8,G(X)=x8 + x5 + x4 + 1,就是1001 1000 )

(注意除法中的用到的加减不是一般的加减,是异或运算!!)

(或者直接用多项式相除也可以,但是更麻烦,因为要把数据流转换为多项式,会死人的!!)

余数和被除数低位异或,得到的数据是校验码!

在数据达到对方时,根据余数是否为0做校验。


WingForce 2005-06-20
  • 打赏
  • 举报
回复
楼上讲的太专业了
我来用土话讲一下:
所谓CRC曼,就是什么循环冗余校验,Cycle Redundency Check(拼写错误概不负责)
校验,目的就是防止一段码流出错
显然,任何信息,都可以在计算机中表示成一串2进制比特流,为了在传输中保证这个比特流没有出错,采用校验的办法.
CRC校验就是把这串比特流看作一个超级大的整数,所谓生成多项式,实际上是一个由数学家证明,XX特性比较好的另外一个数字而已.
比如:G(X)=x8 + x5 + x4 + 1
就简单理解为: 1001 1000 这个二进制数
然后,用前面那个我们看出来的超级大整数"除以"这个二进制数,因为是整数除法,所以最后会得到一个余数,一个商.商就不要了,余数显然是8位的,这个余数就是CRC校验和.
8为CRC校验,就是说如果前面的比特流长度一定,有1/256的概率发生重复.
传送的时候,把校验和一起传过去,然后在计算一遍,发现校验和一样,说明比特流正确的概率是一个异常大的数(不记得怎么算了...)
所以前面的除以要加引号,是因为实际的CRC校验,不是做整数除法,而是不停的将比特流与生成多项式异或+移位

其实就是一种对大信息的抽样,MD5也差不多

我胡扯的,高手指点
horisly 2005-06-20
  • 打赏
  • 举报
回复
G(X)=x8 + x5 + x4 + 1
====
这叫做生成多项式。4位、16位、32位的生成多项式都有了标准(就是可以通用的多项式)。
假设你要发送的消息为m(x). G(X)=x8 + x5 + x4 + 1.
其中G(x)表示为8阶(最高位指数为8).即要把m(x)左移8位(相当于在右边添加8个零),得到F(x).
用F(x)模2除以G(x),得到的余数就是crc码
ljdone 2005-06-20
  • 打赏
  • 举报
回复
我要的crc的结果应该是8位的,前面是16位CRC的算法吧
还有,G(X)=x8 + x5 + x4 + 1的多项式应该体现在什么地方哦
ljdone 2005-06-20
  • 打赏
  • 举报
回复
多谢jixingzhong(瞌睡虫)
请问8位crc中G(X)=x8 + x5 + x4 + 1表现在什么地方了?
jixingzhong 2005-06-20
  • 打赏
  • 举报
回复
另外,你可以去这里

http://www.xhl.com.cn/download1/1.asp?page=11&bigdownid=4&bigdownname=%E6%BA%90%E7%A8%8B%

E5%BA%8F


软件名称:CRC-8
文件格式: c
文件大小: 661B
jixingzhong 2005-06-20
  • 打赏
  • 举报
回复
按半字节计算CRC

unsigned cal_crc(unsigned char *ptr, unsigned char len) {
unsigned int crc;
unsigned char da;
unsigned int crc_ta[16]={ /* CRC余式表 */
0x0000,0x1021,0x2042,0x3063,0x4084,0x50a5,0x60c6,0x70e7,
0x8108,0x9129,0xa14a,0xb16b,0xc18c,0xd1ad,0xe1ce,0xf1ef,
}

crc=0;
while(len--!=0) {
da=((uchar)(crc/256))/16; /* 暂存CRC的高四位 */
crc<<=4; /* CRC右移4位,相当于取CRC的低12位)*/
crc^=crc_ta[da^(*ptr/16)]; /* CRC的高4位和本字节的前半字节相加后查表计算CRC,
然后加上上一次CRC的余数 */
da=((uchar)(crc/256))/16; /* 暂存CRC的高4位 */
crc<<=4; /* CRC右移4位, 相当于CRC的低12位) */
crc^=crc_ta[da^(*ptr&0x0f)]; /* CRC的高4位和本字节的后半字节相加后查表计算CRC,
然后再加上上一次CRC的余数 */
ptr++;
}
return(crc);
}

(。*ptr指向发送缓冲区的首字节,len是要发送的总字节数,CRC余式表是按0x11021多项式求出的)


楼主做个参考!
jixingzhong 2005-06-20
  • 打赏
  • 举报
回复
按位计算CRC

unsigned int cal_crc(unsigned char *ptr, unsigned char len) {
unsigned char i;
unsigned int crc=0;
while(len--!=0) {
for(i=0x80; i!=0; i/=2) {
if((crc&0x8000)!=0) {crc*=2; crc^=0x1021;} /* 余式CRC乘以2再求CRC */
else crc*=2;
if((*ptr&i)!=0) crc^=0x1021; /* 再加上本位的CRC */
}
ptr++;
}
return(crc);
}




按字节计算CRC


unsigned int cal_crc(unsigned char *ptr, unsigned char len) {
unsigned int crc;
unsigned char da;
unsigned int crc_ta[256]={ /* CRC余式表 */
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
0x 1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,
0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0
};

crc=0;
while(len--!=0) {
da=(uchar) (crc/256); /* 以8位二进制数的形式暂存CRC的高8位 */
crc<<=8; /* 左移8位,相当于CRC的低8位乘以 */
crc^=crc_ta[da^*ptr]; /* 高8位和当前字节相加后再查表求CRC ,再加上以前的CRC */
ptr++;
}
return(crc);
}

ljdone 2005-06-20
  • 打赏
  • 举报
回复
CRC啊,是一种校验算法啊
cadinfo 2005-06-20
  • 打赏
  • 举报
回复
问题什么意思,楼主能否表达清楚一些
是多项式方程组还是,多项式方程求解。

后者好解一些,直接调用FORTRAN的函数
前者就比较麻烦,可以使用结式消去法,
可以使用优化算法,例如LM,
也可以使用微分弧长连续同伦算法,你可以到网上找HOMOPACK,但是必须数学基础过得去才能看懂。

70,037

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧