文件解压缩时CRC校验错误的解决方法,很灵的!

文件解压缩时CRC校验错误的解决方法,很灵的!
文件解压缩时CRC校验错误的解决方法,很灵的!

文件解压缩时CRC校验错误的解决方法,很灵的!

办法一:

WinRAR本身就带有压缩包修复功能。双击打开要解压的winrar 压缩包文件,点击菜单“工具”下的“修复压缩文件”即可,快捷键是“ALT+R”。此法可修复一部分压缩包的常规错误,但是成功率不高。你可以试着连续修复几次。WinRAR的这个功能对压缩包里有很多文件且文件容量都比较小的情况比较适用。

办法二:

双击打开要解压的winrar压缩包文件(不是解压,而是用WinRAR打开),选中你要解压缩的文件,单击鼠标右键,在弹出的菜单里选择“无需确认直接解压缩”,快捷键是“ALT+W”。用此方法,不管是好的压缩包还是坏的压缩包,统统畅行无阻,成功率100%!

办法三:釜底抽薪法!

其原理就是让RAR压缩包内损坏的文件解压缩出来,不理会WinRAR的警告,能解压多少就解压多少。解压缩软件还是用WinRAR,不过要做小小的设置,鼠标右键点击要解压缩的文件包,依次选择:winrar - 解压文件(A) ,在解压路径和选项卡中勾选“保留损坏的文件”复选框,点击确定开始解压缩。不要理

会解压缩出错的信息,解压缩结束之后你会发现损坏的文件被解压出来了。经过这样解压出来的损坏文件能正常使用的几率还是非常高的。

预防工作很重要:

其实RAR压缩包出错的解决方法主要是以预防为主!如果没有预防,等到真正出了问题,技术上也是没办法完美解决的!像循环冗余校验码(CRC)出错这种情况,如果RAR压缩包不包含恢复记录的话,用户自己想要修复CRC是不可能的!本文的主要目的是想告诉大家一些出错的原因以及讨论一些从根本上预防出错和把损失减少到最小的办法而已!

预防措施:

1.做好恢复记录

原始RAR压缩包在压缩时,如果选择放置恢复记录,这样用户下载后即使CRC出错也有自己修复的机会!

2.采取分卷压缩

采取分卷压缩的方法便可较大地减少因为出现不可恢复的错误带来的损失。

3.老文件也加恢复记录

有人也许会问,新压缩的RAR压缩包可以加入恢复记录,那么已经压缩过的RAR包有没有办法也加上恢复记录呢?给已经压缩好的RAR压缩包加上恢复纪录是有办法的,只需要打开压缩

包,在“命令”菜单中选择“保护压缩文件防止损害”即可。在“资源管理器”中右击一个文件,选择Winrar→“添加到压缩文件”后,在打开的“压缩文件名和参数”窗口中选中“添加恢复记录”复选框,再单击“高级”标签,在这里即可设置以压缩文件总大小为准的百分比,其最大允许值为10%。较大的恢复记录允许连续损坏时更多的恢复可能,但同时也增加了压缩文件的大小,因此1~3%是较为合适的数值(目前国际上通用的设置为3%)。最后单击“确定”按钮压缩所选文件。

这样压缩出来的压缩包就带有了CRC32校验信息,一旦在解压过程中出现“CRC校验失败,文件被破坏”的提示,我们便可以通过点击winrar软件工具栏里的修复工具按钮来修复文件。

CRC16校验程序

CRC16校验程序 -------------------------------------------------------------------------------- 作者:转载 //CRC16校验在通讯中应用广泛,这里不对其理论进行讨论,只对常见的3种 //实现方法进行测试。方法1选用了一种常见的查表方法,类似的还有512字 //节、256字等查找表的,至于查找表的生成,这里也略过。 // ---------------- POPULAR POLYNOMIALS ---------------- // CCITT:x^16 + x^12 + x^5 + x^0 (0x1021) // CRC-16: x^16 + x^15 + x^2 + x^0 (0x8005) #define CRC_16_POLYNOMIALS 0x8005 // -------------------------------------------------------------- // CRC16计算方法1:使用2个256长度的校验表 // -------------------------------------------------------------- const BYTE chCRCHTalbe[] = // CRC 高位字节值表{ 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40 }; const BYTE chCRCLTalbe[] = // CRC 低位字节值表{ 0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 0x07, 0xC7,

CRC16校验-C语言代码

//CRC16校验在通讯中应用广泛,这里不对其理论进行讨论,只对常见的3种 //实现方法进行测试。方法1选用了一种常见的查表方法,类似的还有512字 //节、256字等查找表的,至于查找表的生成,这里也略过。 // ---------------- POPULAR POLYNOMIALS ---------------- // CCITT: x^16 + x^12 + x^5 + x^0 (0x1021) // CRC-16: x^16 + x^15 + x^2 + x^0 (0x8005) #define CRC_16_POLYNOMIALS 0x8005 // -------------------------------------------------------------- // CRC16计算方法1:使用2个256长度的校验表 // -------------------------------------------------------------- const BYTE chCRCHTalbe[] = // CRC 高位字节值表 { 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40 }; const BYTE chCRCLTalbe[] = // CRC 低位字节值表{ 0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 0x07, 0xC7, 0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09, 0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9,

CRC16校验C语言程序源码-(附完整的可执行的C语言代码)

CRC16校验C语言程序源码-(附完整的可执行的C语言代码)

CRC16校验C语言程序源码(附完整的可执行的C语言代码) //CRC16校验在通讯中应用广泛,这里不对其理论进行讨论,只对常见的2种 //实现方法进行测试。 方法一:查表法(256长度的校验表) 速度快,准确,但是对于单片机设备存储占用大,且校验表长度大,输入时容易出现错误。 // ---------------- POPULAR POLYNOMIALS ---------------- // CCITT: x^16 + x^12 + x^5 + x^0 (0x1021) // CRC-16: x^16 + x^15 + x^2 + x^0 (0x8005) #define CRC_16_POLYNOMIALS 0x8005 const BYTE chCRCHTalbe[] = // CRC 高位字节值表 { 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40 }; const BYTE chCRCLTalbe[] = // CRC 低位字节值表 { 0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 0x07, 0xC7, 0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E,

CRC校验解读

三种常用的CRC16校验算法的C51程序的优化2009-10-10 09:34:17| 分类:技术知识| 标签:|字号大 CRC校验又称为循环冗余校验,是数据通讯中常用的一种校验算法。它可以有效的判别出数据在传输过程中是否发生了错误,从而保障了传输的数据可靠性。 CRC校验有多种方式,如:CRC8、CRC16、CRC32等等。在实际使用中,我们经常使用CRC16校验。CRC16校验也有多种,如:1005多项式、1021多项式(CRC-ITU)等。在这里我们不讨论CRC算法是怎样产生的,而是重点落在几种算法的C51程序的优化上。 计算CRC校验时,最常用的计算方式有三种:查表、计算、查表+计算。一般来说,查表法最快,但是需要较大的空间存放表格;计算法最慢,但是代码最简洁、占用空间最小;而在既要求速度,空间又比较紧张时常用查表+计算法。 下面我们分别就这三种方法进行讨论和比较。这里以使用广泛的51单片机为例,分别用查表、计算、查表+计算三种方法计算1021多项式(CRC-ITU)校验。原始程序都是在网上或杂志上经常能见到的,相信大家也比较熟悉了,甚至就是正在使用或已经使用过的程序。 编译平台采用Keil C51 7.0,使用小内存模式,编译器默认的优化方式。 常用的查表法程序如下,这是网上经常能够看到的程序范例。因为篇幅关系,省略了大部分表格的内容。 code unsigned int Crc1021Table[256] = { 0x0000, 0x1021, 0x2042, 0x3063,... 0x1ef0 }; unsigned int crc0(unsigned char *pData, unsigned char nLength) { unsigned int CRC16 = 0;

CRC终于搞成了

今晚看了好久CRC,最后还有没有很明白。但是做为一个做工程的,有结果就好了。 我要用的不是标准的CRC公式,是X8+1这个,呵呵。下面开始总结。 CRC用到的主要是模2除法,开始看得一头雾水,只有把这个弄清楚了,后来才有了思路。才知道CRC的计算过程。(此处是重点,我费了很多劲儿理解,省去若干字。)不知道计算过程,程序是绝对不能看懂的。 还有这么一句话:多项式的MSB略去不记,因其只对商有影响而不影响余数。就是说对于CRC-CCITT=X16+X12+X5+1,可以只用0x1021,bit16位的1不要了,只留下bit12、5、0。(参考一篇modbus的说明) 记住这两点,再参考下面一段话: 生成CRC-16校验字节的步骤如下: ①装如一个16位寄存器,所有数位均为1。 ②该16位寄存器的高位字节与开始8位字节进行“异或”运算。运算结果放入这个16位寄存器。 ③把这个16寄存器向右移一位。 ④若向右(标记位)移出的数位是1,则生成多项式1010000000000001和这个寄存器进行“异或” 运算;若向右移出的数位是0,则返回③。 ⑤重复③和④,直至移出8位。 ⑥另外8位与该十六位寄存器进行“异或”运算。 ⑦重复③~⑥,直至该报文所有字节均与16位寄存器进行“异或”运算,并移位8次。 ⑧这个16位寄存器的内容即2字节CRC错误校验,被加到报文的最高有效位。 别的都是弯路,以上是最清楚的、实惠的解释了。本文最后,附上另一位网游的文章,也给我很大启发。 下面是成功的程序: unsigned short crc(unsigned char *addr, int num) { int i; while (num--) { crc8 ^= *addr++;

CRC16校验程序-C语言

#include <> /* Table of CRC values for high–order byte */ unsigned char auchCRCHi[] = { 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40 } ; /* Table of CRC values for low–order byte */ unsigned char auchCRCLo[] = { 0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 0x07, 0xC7, 0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09, 0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A, 0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC, 0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3, 0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32, 0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4, 0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A, 0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29, 0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF, 0x2D, 0xED, 0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26, 0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60, 0x61, 0xA1, 0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67, 0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F, 0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68, 0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA, 0xBE, 0x7E, 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5, 0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 0x70, 0xB0, 0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92, 0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C, 0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89, 0x4B, 0x8B, 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C, 0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, 0x43, 0x83, 0x41, 0x81, 0x80, 0x40 };

Modbus CRC校验程序

Modbus CRC校验程序 基本在网上对于MODBUS 的CRC校验程序都能找到两个版本,一个是直接运算的,一个是查表法的。首先来看一下直接运算的算法运算步骤如下:步驟1:令16-bit 寄存器(CRC 暫存器) = FFFFH. 步驟2:Exclusive OR 第一個8-bit byte 的訊息指令與低位元16-bit CRC 寄存器, 做Exclusive OR ,將結果存入CRC 寄存器內。 步驟3:又移一位CRC 寄存器,將0 填入高位處。 步驟4:檢查右移的值,如果是0, 將步驟3 的新值存入CRC 寄存器內, 否則ExclusiveOR A001H 與CRC 寄存器,將結果存入CRC 寄存器內。 步驟5:重複步驟3~步驟4,將8-bit 全部運算完成。 步驟6:重複步驟2~步驟5,取下一個8-bit 的訊息指令,直到所有訊息指令運算完成。 最後,得到的CRC 寄存器的值,即是CRC 的檢查碼。值得注意的是CRC 的檢查碼必須交換放置於訊息指令的檢查碼中。网上能找到的基本代码如下[cpp] view plaincopyprint?uint16 CRC16_Check(uint8 *Pushdata,uint8 length) { uint16 Reg_CRC=0xffff; uint8 Temp_reg=0x00; uint8 i,j; for( i = 0;

i<length; i ++) { Reg_CRC^= *Pushdata++; for (j = 0; j<8; j++) { if (Reg_CRC & 0x0001) Reg_CRC=Reg_CRC>>1^0xA001; else Reg_CRC >>=1; } } return (Reg_CRC); } 基本算法是这个意思来着的,但答案其实是错的,校验没错为何说错呢,这里程序中的少了一句:值得注意的是CRC 的檢查碼必須交換放置於訊息指令的檢查碼中意思就是高字节地位输出,低字节高位输出。翻阅GOOGLE、百度,发现什么样式的都有,直接高字节高位输出的有,高字节低位输出的也有。究竟哪个才是对的呢,经翻阅《GBT19582.1-2008基于Modbus协议的工业自动化网络规范第二部》中规范中crc 占2个字节,低字节在数据流的倒数第二个字节,而高字节在数据流最末端,即应正了高字节低位输出的做法修改程序应该如下的才是正确:如今那么多错误程序真是误人子弟啊~ 真的要用人家的程序拿来也要阅读几次了解了才能用,不然那错的都不知道了[cpp] view plaincopyprint?uint16 CRC16_Check(uint8 *Pushdata,uint8 length) { uint16 Reg_CRC=0xffff; uint8 Temp_reg=0x00; uint8 i,j; for( i = 0; i<length; i ++) { Reg_CRC^= *Pushdata++; for (j = 0; j<8; j++) { if (Reg_CRC & 0x0001) Reg_CRC=Reg_CRC>>1^0xA001; else

16位CRC校验码计算程序

/*************************************************************** 16位CRC计算方法 1.预置1个16位的寄存器为十六进制FFFF(即全为1);称此寄存器为CRC寄存器;2.把第一个8位二进制数据(既通讯信息帧的第一个字节)与16位的CRC寄存器的低8位相异或,把结果放于CRC寄存器; 3.把CRC寄存器的内容右移一位(朝低位)用0填补最高位,并检查右移后的移出位;4.如果移出位为0:重复第3步(再次右移一位); 如果移出位为1:CRC寄存器与多项式A001(1010 0000 0000 0001)进行异或;5.重复步骤3和4,直到右移8次,这样整个8位数据全部进行了处理; 6.重复步骤2到步骤5,进行通讯信息帧下一个字节的处理; 7.将该通讯信息帧所有字节按上述步骤计算完成后,得到的16位CRC; *****************************************************************/ /**************************************************************************** 名称: UART_CRC16_Work() 说明: CRC16校验程序 参数: *CRC_Buf:数据地址 CRC_Leni:数据长度 返回: CRC_Sumx:校验值 *****************************************************************************/ unsigned int UART_CRC16_Work(unsigned char *CRC_Buf,unsigned char CRC_Leni) { unsigned char i,j; unsigned int CRC_Sumx; CRC_Sumx=0xFFFF; for(i=0;i>=1; CRC_Sumx^=0xA001; } else

crc校验详解

CRC校验专题 以CRC-16为例,说明CRC的计算过程: 1.设置CRC寄存器,并给其赋值FFFF(hex)。 2.将数据的第一个8-bit字符与16位CRC寄存器的低8位进行异或,并把结果存入CRC寄存器。 3.CRC寄存器向右移一位,MSB补零,移出并检查LSB。 4.如果LSB为0,重复第三步;若LSB为1,CRC寄存器与多项式码相异或。 5.重复第3与第4步直到8次移位全部完成。此时一个8-bit数据处理完毕。 6.重复第2至第5步直到所有数据全部处理完成。 7.最终CRC寄存器的内容即为CRC值。 翻译: 1.意思是首先寄存器中的值是1111111111111111 2.数据第一个字节一个字节=8位用二进制表示就是【00000000-11111111】之间用 这个数值跟寄存器中的16个1中的后8位进行异或(异或不知道什么意思的自己查简单理解就是同为0 异为1)然后把这个数值保存到寄存器中 3.判断最后一位是否为0 如果为0寄存器中的值向右移动一位前面补零如果为1 拿 寄存器中的值与多项式进行异或。 4.检查当前寄存器中的最后一位如果是0 重复第三步;如果是寄存器中的值与多项式 进行异或 5.重复3与4直到8此移位完成。 6.重复第2到第五步知道正规数组的数据验证完成 7.最终计算出的就是CRC的值 实例: 实例byte[] bufs=new byte[]{0x2f,0x12,0x31} crc16 多项式码假设是0x8408 二进制形式就是1000010000001000 1crc=0xffff; 用二进制表示就是1111111111111111 2拿出bufs中第一个字节0x2f 二进制表示00101111 跟寄存器中的后8位进行异或得到1111111111010000 3判断CRC寄存器中最后一位当前为0 寄存器右移一位得到0111111111101000 (如果为1就与多项式进行异或) 4判断当前寄存器中的值当前最后一位为0 所以重复第三步继续右移得到0011111111110100 最后还是0 在重复第三步0001111111111010 最后还是0 继续第三步0000111111111101 这时最后一位为1了这时与多项式进行异或得到1011101111111001 5重复判断知道判断完8次 6然后再重复第2到第5步直到上面数组中的bufs中三个字节验证完 7最终寄存器中的值就是crc值 下面进行实战C# code 分析

CRC8校验分析(修正版)

CRC即循环冗余校验码(Cyclic Redundancy Check):是数据通信领域中最常用的一种差错校验码,其特征是信息字段和校验字段的长度可以任意选定。(网上流行的这一篇文章,前后两种算法得出来的CRC校验码并不一样,经过多次比对,发现查表法算出来的是正确的.一般性算法却不对,最后总结出来的是每一字节的被除数要反过来读取,算完后余数[即CRC码]也要反过来读取才对,不知何故,如果你懂,请发博文告诉大家.) CRC校验可以简单地描述为:例如我们要发送一些数据(信息字段),为了避免一些干扰以及在接收端的对读取的数据进行判断是否接受的是真实的数据,这时我们就要加上校验数据(即CRC校验码),来判断接收的数据是否正确。在发送端,根据要传送的k位二进制码序列,以一定的规则(CRC校验有不同的规则。这个规则,在差错控制理论中称为“生成多项式”。)产生一个校验用的r位校验码(CRC码),附在原始信息后边,构成一个新的二进制码序列数共 k+r位,然后发送出去。在接收端,根据信息码和CRC码之间所遵循的规则(即与发送时生成CRC校验码相同的规则)进行检验,校验采用计算机的模二除法,即除数和被除数(即生成多项式)做异或运算,进行异或运算时除数和被除数最高位对齐,进行按位异或运算,若最终的数据能被除尽,则传输正确;否则,传输错误。 CRC8即最终生成的CRC校验码为1字节,其生成多项式,生成多项式为g(x)=x8+x5+x4+1,相当于g(x)=1·x8+0·x7+0·x6+1·x5+1·x4+0·x3+0·x2+0·x1+1·x0,即对应的二进制数为100110001。 CRC8校验算法: 1.CRC8校验的一般性算法: 例如:信息字段代码为: 0X01 0X02 ————对应m(x)=x8+x (00000001) (00000010) 反过来读取,即为10000000 01000000 生成多项式为:g(x)=x8+x5+x4+1 ————对应g(x)的二进制代码为:100110001 现在我们将要对2字节数据0x0102生成CRC8校验码,并最终将生成的1字节CRC校验码跟在0x0102的后面,即0x01 02 ##,(##即8为CRC码),最终生成的3字节数据就是经CRC8校验生成的数据。 先计算x8m(x)=x16+x9,对应的2进制数为:10000000 01000000 00000000 。可以看到这样运算所得到的结果其实就是将信息字段代码的数左移8位。因为最终要将生成的8位CRC8校验码附在信息字段的后面,所以要将信息字段的数左移8位。最后用x8m(x)得到的二进制数对生成多项式g(x)进行模二运算,最终的余数(其二进制数的位数一定比生成多项式g(x)的位数小)就是所要的CRC8校验码。

crc16校验 用VB编写的CRC校验程序

用VB编写的CRC校验程序 Private Sub Command1_Click() Dim bcrc%, gp&, bdf& bcrc值为整型, gp值为长整型, bdf值为长整型 bcrc = 16 用CRC—16位校验 gp = V al("&H" & CStr(Text2.Text) & "&") gp为生成多项式缺省为11021(16进制)bdf = Val("&H" & CStr(Text1.Text) & "&") bdf为原值 Text3 = Hex(calcrc(bcrc, gp, bdf)) 为生成的CRC值 End Sub Function calcrc(bcrc As Integer, gp As Long, bdf As Long) As Long Dim c1&, c2& Dim a1%, prec1& Dim leftvalue%, a1shift% If bdf = 0 Then calcrc = 0 Exit Function End If a1 = (Len(Hex(bdf)) - 1) * 4 a1 ={原值(16进制)的字符数目-1}*4 c1 = bdf * 2 ^ bcrc 进行异或运行前,把原值(2进制)后面加16个0 leftvalue = Val("&H" & Mid(Hex(bdf), 1, 1)) 原值的左边第1位(最高位)数值(16进制)If leftvalue >= 1 Then a1shift = 1 原值的最高位=1 偏差=1 If leftvalue >= 2 Then a1shift = 2 原值的最高位=2或3 偏差=2 If leftvalue >= 4 Then a1shift = 3 原值的最高位>=4,<=7 偏差=3 If leftvalue >= 8 Then a1shift = 4 原值的最高位>=8 偏差=4 a1 = a1 + (a1shift - 1) 原值(后面加16个0)与生成多项式的二进制码的个数差c2 = gp * 2 ^ a1 把生成多项式的后面也相应加a1个0 Do prec1 = c1 c1 = c1 Xor c2 原值与生成多项式进行异或 Do a1 = a1 – 1 a1数值减1 If c1 > prec1 Then 如果异或的结果大于原值,说明原值的左边第1位(最高位)为0 c1 = prec1 Xor (gp * 2 ^ a1) 把a1的值减少一位后,继续异或 Else Exit Do

CRC16校验C语言程序源码 (附完整的可执行的C语言代码)

CRC16校验C语言程序源码(附完整的可执行的C语言代码) //CRC16校验在通讯中应用广泛,这里不对其理论进行讨论,只对常见的2种 //实现方法进行测试。 方法一:查表法(256长度的校验表) 速度快,准确,但是对于单片机设备存储占用大,且校验表长度大,输入时容易出现错误。 // ---------------- POPULAR POLYNOMIALS ---------------- // CCITT: x^16 + x^12 + x^5 + x^0 (0x1021) // CRC-16: x^16 + x^15 + x^2 + x^0 (0x8005) #define CRC_16_POLYNOMIALS 0x8005 const BYTE chCRCHTalbe[] = // CRC 高位字节值表 { 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40 }; const BYTE chCRCLTalbe[] = // CRC 低位字节值表 { 0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 0x07, 0xC7, 0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09, 0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A, 0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC, 0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,

相关主题
相关文档
最新文档