Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1433126
  • 博文数量: 1334
  • 博客积分: 645
  • 博客等级: 上士
  • 技术积分: 5762
  • 用 户 组: 普通用户
  • 注册时间: 2012-07-25 16:56
文章分类

全部博文(1334)

文章存档

2014年(108)

2013年(1059)

2012年(169)

分类:

2012-12-07 17:36:27

:转载时请以超链接形式标明文章原始出处和作者信息及本声明
http://kware.blogbus.com/logs/30741819.html

1. CRC(Cyclic Redundancy Checksum) 校验原理
   随着数据传输速度的增大,设备间所传递的数据的准确性变得越来越重要。设备利用类似于校验和的 CRC 技
   术给每个传输的数据增加附加的代码位。接受设备通过解译附加的代码以核实数据被准确传送。

   流行的多项式常数(Polynominal):
   CCITT:   x^16 + x^12 + x^5 + x^0  (0x1021)
   CRC-16:  x^16 + x^15 + x^2 + x^0  (0x8005)
   CRC-32:  ...                      (0x04C11DB7)

   如果两个文件具有相同的 CRC,就意味着两个文件是相同的,CRC是一个检查一个文件每个字节的函数,文件
   的任何哪怕微小改变,都会产生一个不同的 CRC 数,CRC 函数常用于很多程序以验证文件,如 Zip 等。

2. Modulo-2 Binary Division
   Generator Polynominal, Quotient, Message, Remainder
                  10101100     Quotient
      Polyminal ______________
         11011 / 11100101zzzz  Message,  Last zzzz is c-bits Zero.
                 11011
                  01111
                  00000
                   11110
                   11011
                    01011
                    00000
                     10110
                     11011
                      11010
                      11011
                       00010
                       00000
                        00100
                        00000
                         0100  Remainder = CRC (c-bits)

   以2为模的除法流程如下:
   1) 把消息的前 c+1 位调进余数(remainder);
   2) 从原始消息的最高位开始,逐位检查 c+1 位余数:
      - 如果余数的最高位为 1,除数(divisor/polynominal)就被“说成”去除,商数标 1, 同时计算新余
        数,做法如下:
        * 设定商数相应位为 1,且:
        * 异或(XOR)余数和除数,并存储结果为新余数;
      - 否则(首位为 0):
        * 设定商数相应位为 0,且:
        * 异或(XOR)余数和 0,并存储结果为新余数(无效);
      - 左移余数一位, 末位为新进来的消息位;

3. 类 CRC16 定义:
   private short crc = (short)0xFFFF;                 // CRC16 类属性 crc 校验和,初值
   private static short polynominal = (short)0x8005;  // CRC16 类静态常数?

   // 填入一个位串到 crc 计算中。
   public void add_bits(int bitstring, int length) {
     int bitmask = 1 << (length - 1);     // 0 ~ 31 位,
     do {                                 // 对要加入校验的值从高到低逐位循环
       if (((crc & 0x8000) == 0) ^        // 如果 CRC 高位为 1 而要校验的位为 0
         ((bitstring & bitmask) == 0 ))   //   或 CRC 高位为 0 而要校验的位为 1,则执行:
       {
         crc <<= 1;                       // crc 向左循环一位
         crc ^= polynomial;               // crc 1062
       } else
         crc <<= 1;                       // crc 向左循环一位
     } while ((bitmask >>>= 1) != 0);     // 循环掩码右移一位
   }

阅读(236) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~