Java CRC32的用法

1版地址:http://www.repairfaq.org/filipg/LINK/F_crc_v31.html 

我参考的地址:http://www.jdzj.com/data/program/1755.htm

下面是我的理解:

感觉,crc32 的用途,就是生成一个唯一的值。

CRC32,定义的方法很少,我用到的有这么两个。

<span style="font-family: Arial, Helvetica, sans-serif;">
</span><pre name="code" class="java"><span style="font-family: Arial, Helvetica, sans-serif;">DivisionType是一个字符串,转化成byte数组。</span>

CRC32 crc = new CRC32();crc.update(DivisionType.getBytes());crc.getValue();


也就是说,CRC32,可以,.update();方法,将一个byte数组,或者一个int类型的值,

然后,再用,.getValue();获取,刚才用update方法设置后,生成的唯一的值。

好好利用这一个方法,可以做到很多事情哦,亲~~

再下面是复制第二个链接,我参考的。

2.1  什么是CRC

 在远距离数据通信中,为确保高效而无差错地传送数据,必须对数据进行校验即差错控制。循环冗余校验CRC(Cyclic Redundancy Check/Code)是对一个传送数据块进行校验,是一种高效的差错控制方法。

CRC校验采用多项式编码方法。多项式乘除法运算过程与普通代数多项式的乘除法相同。多项式的加减法运算以2为模,加减时不进,错位,如同逻辑异或运算。

2.2  CRC的运算规则

 CRC加法运算规则:0+0=0

                  0+1=1

                  1+0=1

                  1+1=0 (注意:没有进位)

CRC减法运算规则:

          0-0=0

                  0-1=1

                  1-0=1

                  1-1=0

 

CRC乘法运算规则:

                  0*0=0

                  0*1=0

                  1*0=0

                  1*1=1

 

CRC除法运算规则:

            1100001010 (注意:我们并不关心商是多少。)

       _______________

10011 ) 11010110110000

        10011,,.,,....

        -----,,.,,....

         10011,.,,....

         10011,.,,....

         -----,.,,....

          00001.,,....

          00000.,,....

          -----.,,....

           00010,,....

           00000,,....

           -----,,....

            00101,....

            00000,....

            -----,....

             01011....

             00000....

             -----....

              10110...

              10011...

              -----...

               01010..

               00000..

               -----..

                10100.

                10011.

                -----.

                 01110

                 00000

                 -----

                  1110 = 余数

 

 

2.3   如何生成CRC校验码

(1) 设G(X)为W阶,在数据块末尾添加W个0,使数据块为M+ W位,则相应的多项式为XrM(X);

  (2) 以2为模,用对应于G(X)的位串去除对应于XrM(X)的位串,求得余数位串;

  (3) 以2为模,从对应于XrM(X)的位串中减去余数位串,结果就是为数据块生成的带足够校验信息的CRC校验码位串。

 

2.4  可能我们会问那如何选择G(x)

    可以说选择G(x)不是一件很容易的事。一般我们都使用已经被大量的数据,时间检验过的,正确的,高效的,生成多项式。一般有以下这些:

   16 bits: (16,12,5,0)                                               [X25 standard]

             (16,15,2,0)                                                 ["CRC-16"]

   32 bits: (32,26,23,22,16,12,11,10,8,7,5,4,2,1,0)        [Ethernet]

                        

                        三:  如何用软件实现CRC算法

 

      现在我们主要问题就是如何实现CRC校验,编码和解码。用硬件实现目前是不可能的,我们主要考虑用软件实现的方法。

     以下是对作者的原文的翻译:

      我们假设有一个4 bits的寄存器,通过反复的移位和进行CRC的除法,最终该寄存器中的值就是我们所要求的余数。

         

           3   2   1   0   Bits

          +---+---+---+---+

 Pop   <-- |   |   |   |   | <----- Augmented message(已加0扩张的原始数据)

          +---+---+---+---+

 

       1    0   1   1   1   = The Poly

 

(注意: The augmented message is the message followed by W zero bits.)

 

   依据这个模型,我们得到了一个最最简单的算法:

   把register中的值置0.

   把原始的数据后添加r个0.

   While (还有剩余没有处理的数据)

      Begin

      把register中的值左移一位,读入一个新的数据并置于register的0 bit的位置。

      If (如果上一步的左移操作中的移出的一位是1)

         register = register XOR Poly.

      End

   现在的register中的值就是我们要求的crc余数。

  我的学习笔记:

 可为什么要这样作呢?我们从下面的实例来说明:        

            1100001010

        _______________

10011 ) 11010110110000

        10011,,.,,....

        -----,,.,,....

-》     10011,.,,....

         10011,.,,....

         -----,.,,....

-》      00001.,,....

          00000.,,....

          -----.,,....

           00010,,....

           00000,,....

           -----,,....

            00101,....

            00000,....

 

   我们知道G(x)的最高位一定是1,而商1还是商0是由被除数的最高位决定的。而我们并不关心商究竟是多少,我们关心的是余数。例如上例中的G(x)有5位。我们可以看到每一步作除法运算所得的余数其实就是被除数的最高位后的四位于G(x)的后四位XOR而得到的。那被除数的最高位有什么用呢?我们从打记号的两个不同的余数就知道原因了。当被除数的最高位是1时,商1然后把最高位以后的四位于G(x)的后四位XOR得到余数;如果最高位是0,商0然后把被除数的最高位以后的四位于G(x)的后四位XOR得到余数,而我们发现其实这个余数就是原来被除数最高位以后的四位的值。也就是说如果最高位是0就不需要作XOR的运算了。到这我们总算知道了为什么先前要这样建立模型,而算法的原理也就清楚了。

 

以下是对作者的原文的翻译:

 可是这样实现的算法却是非常的低效。为了加快它的速度,我们使它一次能处理大于4 bit的数据。也就是我们想要实现的32 bit的CRC校验。我们还是假设有和原来一样的一个4 "bit"的register。不过它的每一位是一个8 bit的字节。

             3    2    1    0   Bytes

          +----+----+----+----+

   Pop <-- |    |    |    |    | <----- Augmented message

          +----+----+----+----+

 

         1<------32 bits------> (暗含了一个最高位的“1”)

 

  根据同样的原理我们可以得到如下的算法:

  While (还有剩余没有处理的数据)

      Begin

      检查register头字节,并取得它的值

      求不同偏移处多项式的和

      register左移一个字节,最右处存入新读入的一个字节

      把register的值和多项式的和进行XOR运算

      End

 

我的学习笔记:

  可是为什么要这样作呢? 同样我们还是以一个简单的例子说明问题:

  假设有这样的一些值:

 

  当前register中的值: 01001101

  4 bit应该被移出的值:1011

  生成多项式为:      101011100

 

  Top  Register

  ---- --------

  1011 01001101 

  1010 11100   + (CRC XOR)

  -------------

  0001 10101101

 

  首4 bits 不为0说明没有除尽,要继续除:

  0001 10101101 

     1 01011100 + (CRC XOR)

  -------------

  0000 11110001

  ^^^^

  首4 bits 全0说明不用继续除了。

 

  那按照算法的意思作又会有什么样的结果呢?

 

 1010 11100   

 1 01011100+

 -------------

 1011 10111100 

 

 

 1011 10111100

 1011 01001101+


时间: 2024-11-01 01:44:18

Java CRC32的用法的相关文章

java的vector 用法

Vector的用法很简单,这已在前面的例子中得到了证明.尽管我们大多数时候只需用addElement()插入对象,用elementAt()一次提取一个对象,并用elements()获得对序列的一个"枚举".但仍有其他一系列方法是非常有用的.同我们对于Java库惯常的做法一样,在这里并不使用或讲述所有这些方法.但请务必阅读相应的电子文档,对它们的工作有一个大概的认识. 1. 崩溃Java Java标准集合里包含了toString()方法,所以它们能生成自己的String表达方式,包括它们

Java枚举类用法实例

  本文实例讲述了Java枚举类用法.分享给大家供大家参考.具体如下: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 package com.school.stereotype; /** * 活动枚举类型 * @

java-关于Java object的用法

问题描述 关于Java object的用法 class Student { String name; int age; public boolean equals (Object obj) { Student st = null; if(obj instanceof Student) st =(Student)obj; else return false; if(st.name==this.name&&st.age==this.age) return true; else return f

关于java crc32的问题,java提供的那个

问题描述 关于java crc32的问题,java提供的那个 比如我现在要对abc这个字符串进行crc32,那crc32.update后面括号里应该填什么呢??是"abc".getBytes()还是0100000101000002这种啊...文档里写的是int,是指十进制的97吗... 解决方案 填写的是byte数组,如果用十进制表示,就是97,98,99 解决方案二: CRC32之JAVA实现在Java中使用CRC32java 实现CRC32校验

Java中线程用法总结_java

本文实例总结了Java中线程用法.分享给大家供大家参考.具体分析如下: 1.线程是基本调度单元.共享进程的资源,如内存和文件句柄.但有自己的pc(程序计数器),stack(线程栈)及本地变量 2.线程的优势: a) 充分利用多处理器 b) 可以简化模型.特定任务给特定线程.如servlets及rmi等框架. c) 对异步事件的简单处理.如socket,nio使用更复杂.而现在的操作系统支持更大数量的线程. d) 界面的更佳响应 3.内部锁:synchronized块.互斥.可重入(reentra

Java中channel用法总结_java

本文实例总结了Java中channel用法.分享给大家供大家参考.具体分析如下: 1.Channel接口的定义: public interface Channel { public boolean isOpen( ); public void close( ) throws IOException; } 2.Channel的常见类型: FileChannel, SocketChannel, ServerSocketChannel, and DatagramChannel: FileChannel

Java中getResourceAsStream用法分析_java

本文实例讲述了Java中getResourceAsStream用法.分享给大家供大家参考.具体如下: (一)Java中的getResourceAsStream有以下几种情况: 1. Class.getResourceAsStream(String path) : #path 不以'/'开头时默认是从此类所在的包下取资源: #以'/'开头则是从ClassPath根下获取,其原理是通过path构造一个绝对路径,最终还是由ClassLoader来获取资源. 2. Class.getClassLoade

Java RandomAccessFile的用法详解_java

RandomAccessFile RandomAccessFile是用来访问那些保存数据记录的文件的,你就可以用seek( )方法来访问记录,并进行读写了.这些记录的大小不必相同:但是其大小和位置必须是可知的.但是该类仅限于操作文件. RandomAccessFile不属于InputStream和OutputStream类系的.实际上,除了实现DataInput和 DataOutput接口之外(DataInputStream和DataOutputStream也实现了这两个接口),它和这两个类系毫

Java枚举类用法实例_java

本文实例讲述了Java枚举类用法.分享给大家供大家参考.具体如下: package com.school.stereotype; /** * 活动枚举类型 * @author QiXuan.Chen */ public enum EventStatus { /** * 未发布. */ DRAFT("DRAFT", "未发布"), /** * 已发布. */ PUBLISHED("PUBLISHED", "已发布"); /**