打印

CRC高手请进

[复制链接]
1873|12
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
耕在此行|  楼主 | 2008-11-5 14:19 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
unsigned short CRC16(puchMsg, usDataLen) 
unsigned char *puchMsg ; /* 要进行CRC校验的消息 */ 
unsigned short usDataLen ; /* 消息中字节数 */ 
    { 
    unsigned char uchCRCHi = 0xFF ; /* 高CRC字节初始化 */ 
    unsigned char uchCRCLo = 0xFF ; /* 低CRC 字节初始化 */ 
    unsigned uIndex ; /* CRC循环中的索引 */ 
    while (usDataLen--) /* 传输消息缓冲区 */ 
        { 
        uIndex = uchCRCHi ^ *puchMsgg++ ; /* 计算CRC */ 
        uchCRCHi = uchCRCLo ^ auchCRCHi[uIndex} ; 
        uchCRCLo = auchCRCLo][uIndex] ; 
        } 
    return (uchCRCHi << 8 | uchCRCLo) ; 
    } 
有哪位高手能帮忙把上面这段翻译成C语言.

本人这个项目用到MODBUS协议,里面的校验是用CRC校验.
我在网上查很N多资料,看得晕晕乎乎的,没得出个所以然.
现在只好依人家的葫芦画瓢.程序自己写的、流程图别人的。
请高手指出其中的错误:
程序:
bin08 = unsigned char
adr   发送区数据地址,
lenth 数据字节数.
多项式为 CRC_gx=0xa001;
bin16 calculate_crc(bin08* adr, bin08 lenth)
    {
    bin08 i;
    bin16 crc;
    crc = 0xffff;
    while(len--)
        {
        crc ^= *adr;
        for( i=8;i!=0;i-- )
            {
            if( crc & bit15 )
                {
                crc >>= 1;
                crc ^= CRC_gx;
                }
            else
                {
                crc >>= 1;
                }
            }
        adr++;
        }
    return (crc);
    }
流程图:

相关帖子

沙发
耕在此行|  楼主 | 2008-11-5 14:20 | 只看该作者

自己先顶下

高手们不要只看不说啊

使用特权

评论回复
板凳
xwj| | 2008-11-5 17:21 | 只看该作者

去搜索Hotpower的旧帖!

他还有现成好用验算工具

使用特权

评论回复
地板
yewuyi| | 2008-11-5 20:15 | 只看该作者

逮HOTPOWER那老顽童。。。

不过即使估计你逮着他,估计你只会更晕乎乎。。。

使用特权

评论回复
5
hotpower| | 2008-11-5 20:25 | 只看该作者

最近不办公~~~在上小学堂~~~

使用特权

评论回复
6
chunyang| | 2008-11-5 20:33 | 只看该作者

也可以去看看我的Blog

有详细计算方法的流程描述

使用特权

评论回复
7
yihucong| | 2008-11-5 20:52 | 只看该作者

lz,给你个简单的一句话实现的,我已经用过

lz,给你个简单的一句话实现的,我已经用过
//------------------------------CRC function-------------------------------------------
uint Calc_crc(uint wCrc, uchar *byIn, uint cnt) 
{    
     while (cnt--)    { 
        
        wCrc = (wCrc >> 8) ^ *(CRCTable + ((wCrc & 0xff) ^ *(byIn++)));        
     }

    return wCrc;
}
//寄存器初始值初始化为 “1”,(oxffff)
//寄存器组向右移动一个字节
//刚移动的哪个字节与数据字节进行异或运算 得到一个指向索引表的索引
//索引所指的标的值与寄存器组做异或运算
//数据指针加1,如果数据未处理玩 重复
//
// 

使用特权

评论回复
8
yihucong| | 2008-11-5 20:53 | 只看该作者

用到的是查表法,表的值如下所示

 uint xdata CRCTable[256]  = {0x0000, 0xc0c1, 0xc181, 0x0140, 0xc301, 0x03c0, 0x0280, 0xc241,     
                                0xc601, 0x06c0, 0x0780, 0xc741, 0x0500, 0xc5c1, 0xc481, 0x0440,     
                                0xcc01, 0x0cc0, 0x0d80, 0xcd41, 0x0f00, 0xcfc1, 0xce81, 0x0e40,     
                                0x0a00, 0xcac1, 0xcb81, 0x0b40, 0xc901, 0x09c0, 0x0880, 0xc841,     
                                0xd801, 0x18c0, 0x1980, 0xd941, 0x1b00, 0xdbc1, 0xda81, 0x1a40,     
                                0x1e00, 0xdec1, 0xdf81, 0x1f40, 0xdd01, 0x1dc0, 0x1c80, 0xdc41,     
                                0x1400, 0xd4c1, 0xd581, 0x1540, 0xd701, 0x17c0, 0x1680, 0xd641,     
                                0xd201, 0x12c0, 0x1380, 0xd341, 0x1100, 0xd1c1, 0xd081, 0x1040,     
                                0xf001, 0x30c0, 0x3180, 0xf141, 0x3300, 0xf3c1, 0xf281, 0x3240,     
                                0x3600, 0xf6c1, 0xf781, 0x3740, 0xf501, 0x35c0, 0x3480, 0xf441,     
                                0x3c00, 0xfcc1, 0xfd81, 0x3d40, 0xff01, 0x3fc0, 0x3e80, 0xfe41,     
                                0xfa01, 0x3ac0, 0x3b80, 0xfb41, 0x3900, 0xf9c1, 0xf881, 0x3840,     
                                0x2800, 0xe8c1, 0xe981, 0x2940, 0xeb01, 0x2bc0, 0x2a80, 0xea41,     
                                0xee01, 0x2ec0, 0x2f80, 0xef41, 0x2d00, 0xedc1, 0xec81, 0x2c40,     
                                0xe401, 0x24c0, 0x2580, 0xe541, 0x2700, 0xe7c1, 0xe681, 0x2640,     
                                0x2200, 0xe2c1, 0xe381, 0x2340, 0xe101, 0x21c0, 0x2080, 0xe041,     
                                0xa001, 0x60c0, 0x6180, 0xa141, 0x6300, 0xa3c1, 0xa281, 0x6240,     
                                0x6600, 0xa6c1, 0xa781, 0x6740, 0xa501, 0x65c0, 0x6480, 0xa441,     
                                0x6c00, 0xacc1, 0xad81, 0x6d40, 0xaf01, 0x6fc0, 0x6e80, 0xae41,     
                                0xaa01, 0x6ac0, 0x6b80, 0xab41, 0x6900, 0xa9c1, 0xa881, 0x6840,     
                                0x7800, 0xb8c1, 0xb981, 0x7940, 0xbb01, 0x7bc0, 0x7a80, 0xba41,     
                                0xbe01, 0x7ec0, 0x7f80, 0xbf41, 0x7d00, 0xbdc1, 0xbc81, 0x7c40,     
                                0xb401, 0x74c0, 0x7580, 0xb541, 0x7700, 0xb7c1, 0xb681, 0x7640,     
                                0x7200, 0xb2c1, 0xb381, 0x7340, 0xb101, 0x71c0, 0x7080, 0xb041,     
                                0x5000, 0x90c1, 0x9181, 0x5140, 0x9301, 0x53c0, 0x5280, 0x9241,     
                                0x9601, 0x56c0, 0x5780, 0x9741, 0x5500, 0x95c1, 0x9481, 0x5440,     
                                0x9c01, 0x5cc0, 0x5d80, 0x9d41, 0x5f00, 0x9fc1, 0x9e81, 0x5e40,     
                                0x5a00, 0x9ac1, 0x9b81, 0x5b40, 0x9901, 0x59c0, 0x5880, 0x9841,     
                                0x8801, 0x48c0, 0x4980, 0x8941, 0x4b00, 0x8bc1, 0x8a81, 0x4a40,     
                                0x4e00, 0x8ec1, 0x8f81, 0x4f40, 0x8d01, 0x4dc0, 0x4c80, 0x8c41,     
                                0x4400, 0x84c1, 0x8581, 0x4540, 0x8701, 0x47c0, 0x4680, 0x8641,     
                                0x8201, 0x42c0, 0x4380, 0x8341, 0x4100, 0x81c1, 0x8081, 0x4040 };

使用特权

评论回复
9
hyhjjg| | 2008-11-5 21:07 | 只看该作者

片子的空间是有限的,还是移位算法好。

还请大虾贴上非查表算法的代码

使用特权

评论回复
10
hotpower| | 2008-11-5 21:44 | 只看该作者

Modbus CRC 校验码的小程序

使用特权

评论回复
11
耕在此行|  楼主 | 2008-11-6 08:26 | 只看该作者

请教:hotpower

你的多项式是A001吗?

刚才看了MODBUS协议。呵呵 hotpower的应该是A001。

使用特权

评论回复
12
耕在此行|  楼主 | 2008-11-6 10:45 | 只看该作者

我已经找到错误了

用了:hotpower的计算器.
找到了程序错误了.
在这谢谢:hotpower了.

等下再验证下查表法.呵呵 

使用特权

评论回复
13
hotpower| | 2011-12-26 13:00 | 只看该作者
顶起来,掀起密码安全教育风暴~~~

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

40

主题

1108

帖子

0

粉丝