社区
C语言
帖子详情
求CRC-8,G(X)=x8 + x5 + x4 + 1源码
ljdone
2005-06-20 11:27:59
如题
...全文
10484
14
打赏
收藏
求CRC-8,G(X)=x8 + x5 + x4 + 1源码
如题
复制链接
扫一扫
分享
转发到动态
举报
写回复
配置赞助广告
用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,但是必须数学基础过得去才能看懂。
这是一款基于聚鑫 API 的 Dify 文生图插件,采用 Google Gemini 3 Pro Image Preview 模.zip
基于AI的工作效率提升工具(聊天、绘画、知识库、工作流、 MCP服务市场、语音输入输出、长期记忆) | Ai-based productivity tools (Chat,Draw,RAG,Workflow,MCP marketplace, ASR,TTS, Long-te…
综合大作业-大数据2301.doc
综合大作业-大数据2301.doc
柔性电力系统中油浸式变压器的最佳老化极限研究(Matlab代码实现)
柔性电力系统中油浸式变压器的最佳老化极限研究(Matlab代码实现)
docker-compose-linux-
x8
6-64-v5.1.4
Docker Compose 是一个用于定义和运行多容器Docker应用程序的命令行工具
六轴机械臂斗地主发牌代码(回零位置优化版本)
六轴机械臂斗地主发牌代码(回零位置优化版本)
C语言
70,037
社区成员
243,247
社区内容
发帖
与我相关
我的任务
C语言
C语言相关问题讨论
复制链接
扫一扫
分享
社区描述
C语言相关问题讨论
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章