CRC32校验的困惑

ashleycoder 2012-04-11 09:39:48
关于CRC校验的困惑

1 用龚建伟书中的代码CRC16测试:

测试3EA01, 校验码为DC3E

测试3EA01DC3E,校验码为8C26不为0

如果CRC16校验正确的话,应该为0!

2 int Str2Hex(CString str,char *data)
rlen=1 ?
3EA01执行Str2Hex后,字节数不应该是=3吗?

3 如果原数据5位16进制,采用CRC32校验(8位16进制),这种设计不合理吧?
使用CRC32校验,起码原数据是8位16进制以上吧?
...全文
521 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
你这个3EA01是2.5个字节啊? 你的CRC16怎么能算出来的?
引用 楼主 chenquangobeijing 的回复:
本帖最后由 chenquangobeijing 于 2012-08-12 16:44:01 编辑关于CRC校验的困惑 1 用龚建伟书中的代码CRC16测试: 测试3EA01, 校验码为DC3E 测试3EA01DC3E,校验码为8C26不为0 如果CRC16校验正确的话,应该为0! 2 int Str2Hex(CString str,char *d……
xiaohuh421 2012-09-16
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 的回复:]
或者这样问更容易理解些:

CRC32校验可以对最少多少位16进制进行校验?
[/Quote]
1位也是可以的. 也就是说可以能 1Byte的数据计算出 CRC8 CRC16 CRC32的校验值,只是得到的结果不同罢了.
CRC8计算的校验值为8Bit即1个Byte.
CRC16计算出的校验值为16Bit即2个Byte.
CRC32计算出的校验值为32Bit即4个Byte.

CRC32中的32只是表示计算过程中使用的"算法单位"和计算结果的位数.
ashleycoder 2012-09-16
  • 打赏
  • 举报
回复

to xiaohuh421:

你的意思是:比如发送数据"A",用CRC32计算也行。

那为什么不用CRC16或CRC8计算呢?
ashleycoder 2012-09-15
  • 打赏
  • 举报
回复

或者这样问更容易理解些:

CRC32校验可以对最少多少位16进制进行校验?
ashleycoder 2012-09-15
  • 打赏
  • 举报
回复

如果原始数据是5位16进制,采用CRC32校验(8位16进制),
这种设计不合理吧?

是不是采用CRC16校验(4位16进制)更合理?

用过CRC校验的回答下吧!
hdg3707 2012-09-09
  • 打赏
  • 举报
回复
CRC16或CRC32的值并不一定是0,而且基本是不会是0的,发送方把CRC的值一起发出去,接收方收到数据后再来一遍CRC,并把自己CRC的值和收到的对比,如果是一致就说明接收的数据是正确的,否则就是通信失败
Crc实际是根据一个多项式来计算机的,在硬件里就是不断的移位来实现的,在计算机里可以查表来实现,也可以用软件移位来实现.
ashleycoder 2012-09-08
  • 打赏
  • 举报
回复

to dcmilan:
你接受对方“经过CRC16校验的字符串”,你这边要再校验CRC16,那校验码==0

还是等于固定值(固定值具体指什么?)?
  • 打赏
  • 举报
回复
打听一下CRC32主要用在什么领域
我是做电力监控的
有时会用到modbus RTU的CRC16
ashleycoder 2012-08-25
  • 打赏
  • 举报
回复

to stephen_young:

你说的固定值是什么意思,可以举例说明一下吗?
奔跑的北极熊 2012-08-19
  • 打赏
  • 举报
回复
如果结果不为0,是一个固定值也是对的。
傻X 2012-08-18
  • 打赏
  • 举报
回复
我都拿来直接用的。没弄过原理。
ashleycoder 2012-08-18
  • 打赏
  • 举报
回复

给点意见吧
Yofoo 2012-08-17
  • 打赏
  • 举报
回复
1. 你是不是弄成字符串做crc, 应该用16进制内存, 还有注意高低位
2. 3EA01 这个不太规范, 看你代码怎么写的, 要不用 03EA01
3. crc可以给任意长度计算, 短的也没关系
ashleycoder 2012-08-17
  • 打赏
  • 举报
回复

没有人用过CRC校验吗?
CRC(Cyclic Redundancy Check)循环冗余校验码(转) 未记录作者的网址,作者见谅。 是常用的校验码,在早期的通信中运用广泛,因为早期的通信技术不够可靠(不可靠性的来源是通信技术决定的,比如电磁波通信时受雷电等因素的影响),不可靠的通信就会带来‘确认信息’的困惑,书上提到红军和蓝军通信联合进攻山下的敌军的例子,第一天红军发了条信息要蓝军第二天一起进攻,蓝军收到之后,发一条确认信息,但是蓝军担心的是‘确认信息’如果也不可靠而没有成功到达红军那里,那自己不是很危险?于是红军再发一条‘对确认的确认信息’,但同样的问题还是不能解决,红军仍然不敢贸然行动。 对通信的可靠性检查就需要‘校验’,校验是从数据本身进行检查,它依靠某种数学上约定的形式进行检查,校验的结果是可靠或不可靠,如果可靠就对数据进行处理,如果不可靠,就丢弃重发或者进行修复。 CRC码是由两部分组成,前部分是信息码,就是需要校验的信息,后部分是校验码,如果CRC码共长n个bit,信息码长k个bit,就称为(n,k)码。 它的编码规则是: 1、首先将原信息码(kbit)左移r位(k+r=n) 2、运用一个生成多项式g(x)(也可看成二进制数)用模2除上面的式子,得到的余数就是校验码。 非常简单,要说明的:模2除就是在除的过程中用模2加,模2加实际上就是我们熟悉的异或运算,就是加法不考虑进位,公式是: 0+0=1+1=0,1+0=0+1=1 即‘异’则真,‘非异’则假。 由此得到定理:a+b+b=a 也就是‘模2减’和‘模2加’直值表完全相同。 有了加减法就可以用来定义模2除法,于是就可以用生成多项式g(x)生成CRC校验码。 例如: g(x)=x4+x3+x2+1,(7,3)码,信息码110产生的CRC码就是: 11 11101 | 110,0000 111 01 1 0100 1 1101 1001 余数是1001,所以CRC码是110,1001 标准的CRC码是,CRC-CCITT和CRC-16,它们的生成多项式是: CRC-CCITT=x16+x12+x5+1 CRC-16=x16+x15+x2+1 CRC 的计算原理如下(一个字节的简单例子) 11011000 00000000 00000000 <- 一个字节数据, 左移 16b ^10001000 00010000 1 <- CRC-CCITT 多项式, 17b -------------------------- 1010000 00010000 10 <- 中间余数 ^1000100 00001000 01 ------------------------- 10100 00011000 1100 ^10001 00000010 0001 ----------------------- 101 00011010 110100 ^100 01000000 100001 --------------------- 1 01011010 01010100 ^1 00010000 00100001 ------------------- 01001010 01110101 <- 16b CRC 仿此,可推出两个字节数据计算如下:d 为数据,p 为项式,a 为余数 dddddddd dddddddd 00000000 00000000 <- 数据 D ( D1, D0, 0, 0 ) ^pppppppp pppppppp p <- 多项式 P ----------------------------------- ... aaaaaaaa aaaaaaaa 0 <- 第一次的余数 A'''''''' ( A''''''''1, A''''''''0 ) (备注:实际余数) ^pppppppp pppppppp p -------------------------- ... aaaaaaaa aaaaaaaa <- 结果 A ( A1, A0 ) 由此与一字节的情况比较,将两个字节分开计算如下: 先算高字节: dddddddd 00000000 00000000 00000000 <- D1, 0, 0, 0 ^pppppppp pppppppp p <- P ----------------------------------- ... aaaaaaaa aaaaaaaa <- 高字节部分余数 PHA1, PHA0 此处的部分余数与前面两字节算法中的第一次余数有如下关系,即 A''''''''1 = PHA1 ^ D0, A''''''''0 = PHA0 备注:(A XOR B) XOR B= A XOR (B XOR B)=A aaaaaaaa aaaaaaaa <- PHA1, PHA0 ^dddddddd <- D0 ----------------- aaaaaaaa aaaaaaaa <- A''''''''1, A''''''''0 低字节的计算: aaaaaaaa 00000000 00000000 <- A''''''''1, 0, 0 ^pppppppp pppppppp p <- P -------------------------- ... aaaaaaaa aaaaaaaa <- 低字节部分余数 PLA1, PLA0 ^aaaaaaaa <- A''''''''0 , 即 PHA0 ----------------- aaaaaaaa aaaaaaaa <- 最后的 CRC ( A1, A0 ) 规律如下: 设部分余数函数 PA = f( d ) 其中 d 为一个字节的数据(注意,除非 n = 0 ,否则就不是原始数据,见下文) 第 n 次的部分余数 PA( n ) = ( PA( n - 1 ) << 8 ) ^ f( d ) 其中的 d = ( PA( n - 1 ) >> 8 ) ^ D( n ) 其中的 D( n ) 才是一个字节的原始数据。 公式如下: PA( n ) = ( PA( n - 1 ) << 8 ) ^ f( ( PA( n - 1 ) >> 8 ) ^ D( n ) ) 可以注意到函数 f( d ) 的参数 d 为一个字节,对一个确定的多项式 P, f( d ) 的返回值 是与 d 一一对应的,总数为 256 项,将这些数据预先算出保存在表里,f( d )就转换为一 个查表的过程,速度也就可以大幅提高,这也就是查表法计算 CRC 的原理. 在网上找了很多文章,不知为啥,算出的结果都有异样,所以找到一个C写的与在线CRC工具网站是一一对应的,所以将C翻译成delphi, 为delphi增砖添瓦 :) 在线工具: 在线工具1 http://www.lammertbies.nl/comm/info/crc-calculation.html 在线工具2 http://zorc.breitbandkatze.de/crc.html

16,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

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