从按BIT计算转到按BYTE计算,要利用异或的一个性质,具体见前面的文章《再探CRC 》。

其实方法跟逐BIT法是一样的,我们只是利用异或的性质,把数据分成一BYTE一BYTE来计算,一BYTE数据会有256种值,每一种值与POLY(生成多项式)进行模二除法的余数都是唯一的,所以我们可以先把这256个余数先计算出来,放到一个表里,这样对每一BYTE进行模二除求余的计算都节省了。

如果不用查表的方法,逐BYTE法对比逐BIT法没什么区别,因为计算量是一样的,逐BYTE法还会多好多跳转步骤。

使用查表方法,计算一个32位数据只需要异或4次+查表4次,是不是快得多了

以0x035b035b为例

令Reg=0x035b035b

1 .从Reg中取头一个BYTE即0x03扩展成0x03000000与POLY逐BIT模二除求余,得一个u32的TempReg,然后用其与剩下的Reg(0x5b035b00)异或得到更新的Reg

2.再从Reg中取头一个BYTE进行1的步骤,直到最后一Byte计算完毕,因为一个32数据有4个BYTE,所以总共需要计算4次

其实这跟逐BIT计算没什么区别,用《再探CRC 》里的算例里的两种方法实际手算一下,就能体会。

如果我们有之前说的表,那步骤1可以变成:

1 .从Reg中取头一个BYTE即0x03,查表直接得到0x03与POLY逐BIT模二除的余数,得一个u32的TempReg,然后用其与剩下的Reg(0x5b035b00)异或得到更新的Reg

下面就是用逐BYTE法来进行CRC校验的函数:

/*CRC校验程序*/
//输入32位
//多项式,省略最高位1 0x4C11DB7 CCITT-32:   0x04C11DB7  =  x32 + x26 +  x23 + x22 + x16 + x12 +
//                              x11 + x10 + x8 + x7 + x5 + x4 + x2 + x + 1
//数据不revert 结果不revert
//初值0x00000000或0xFFFFFFFF,其实所谓的初值就是原始数据要不要跟0xFFFFFFFF先异或先放到Reg中计算,用0xFFFFFFFF只是为了让别人不
//会一下就看出生成多项式是多少
//结果不异或
//验证网址:http://www.zorc.breitbandkatze.de/crc.html
//算法中数据向左移动,相对手工计算等效于生成多项式向右移动,所以不需要在后面加一大堆0
u32 CRC_Check_Software(u8 *ucpData,u8 Length)
{
    u32 poly=0x4C11DB7; //生成多项式
    u32 Reg=0x00000000; //初值
    u32 tempbyte=;
    u8 i;
    u8 count;
    u8 j=;
    u8 u32DataLen=((Length/)>)?((Length/)+):(Length/);
    u32 uipData[]={};
    //把byte组合成32位一组的数据放入uipData
    ;i<Length;i++)
    {
        uipData[i/]|=((u32)(*(ucpData+i)))<<(*(j-));
        j--;
        )
        {
            j=;
        }
    }
    //以下是算法开始

    //逐BYTE法
    ;count<u32DataLen;count++)
    {
        Reg=uipData[count];
        //Reg^=0xffffffff;//如果初值为0x00000000就把这行注释掉,否则不要注释
        ;i<;i++)
        {
            tempbyte= (( Reg >>  ) & ;//取一个byte
            ;j<;j++)
            {
                if(tempbyte&0x80000000)
                {
                    tempbyte=tempbyte<<;//要异或时Reg的最高位是1,CRC多项式最高位一直就是1,异或后必为0,所以一开始就偷懒把CRC多项式去掉最高位变成
                                       //0x4C11DB7 ,所以相应的这时候要把Reg左移一位,只要异或后边的32位
                    tempbyte^=poly;
                }
                else
                {
                    tempbyte=tempbyte<<;
                }
            }
            Reg=Reg<<; //丢掉计算过的头一个BYTE
            Reg^=tempbyte; //与前一个BYTE的计算结果异或 

        }
    }

    /*位计算算法
    for(i=0;i<u32DataLen;i++)
    {
        Reg=uipData[i];
        Reg^=0xffffffff;//如果初值为0x00000000就把这行注释掉,否则不要注释
        for(j=0;j<32;j++)
        {
            if(Reg&0x80000000)
            {
                Reg=Reg<<1;//要异或时Reg的最高位是1,CRC多项式最高位一直就是1,异或后必为0,所以一开始就偷懒把CRC多项式去掉最高位变成
                                //0x4C11DB7 ,所以相应的这时候要把Reg左移一位,只要异或后边的32位
                Reg^=poly;
            }
            else
            {
                Reg=Reg<<1;
            }

        }
    }
    */

    return Reg;
}

这一部分就是对每一个BYTE模二求余:

;j<;j++)
{
    if(tempbyte&0x80000000)
    {
        tempbyte=tempbyte<<;    // 要异或时Reg的最高位是1,CRC多项式最高位一直就是1,异或后必为0,所以一开始就偷懒把CRC多项式去掉最高位变成
                                // 0x4C11DB7 ,所以相应的这时候要把Reg左移一位,只要异或后边的32位
        tempbyte^=poly;
    }
    else
    {
        tempbyte=tempbyte<<;
    }
} 

是不是就是前一篇文章里的逐BIT法?

最简单的CRC32源码-逐BYTE法的更多相关文章

  1. 最简单的CRC32源码---逐BIT法

    CRC其实也就那么回事,却在网上被传得神乎其神.单纯从使用角度来说,只需要搞明白模二除法,再理解一些偷懒优化的技巧,就能写出自己的CRC校验程序. 下面的代码完全是模拟手算过程的,效率是最低的,发出来 ...

  2. 最简单的CRC32源码-查表法

    这个算法是在逐BYTE法的基础上进行修改的,在上一篇文章里我们说过,如果不查表的话,逐BYTE法和逐BIT法没什么区别,现在我们就把这个算法写出来,注意在调用CRC校验函数前需要先调用表生成函数: u ...

  3. JDK源码之Byte类分析

    一 简介 byte,即字节,由8位的二进制组成.在Java中,byte类型的数据是8位带符号的二进制数,以二进制补码表示的整数 取值范围:默认值为0,最小值为-128(-2^7);最大值是127(2^ ...

  4. 简单看看jdk7源码之java.lang包01

    从今天开始简单开始读一遍jdk的源码,估计这个时间会很长,慢慢啃吧....(首先说一句抱歉,因为很多图都是直接百度扣的,图太多了不能为每一个图附上原版链接,不好意思!) 在网上看了很多的教程,读源码有 ...

  5. Managed DirectX中的DirectShow应用(简单Demo及源码)

    阅读目录 介绍 准备工作 环境搭建 简单Demo 显示效果 其他 Demo下载 介绍 DirectX是Microsoft开发的基于Windows平台的一组API,它是为高速的实时动画渲染.交互式音乐和 ...

  6. 高性能页面加载技术(流水线加载)BigPipe的C#简单实现(附源码)

    一,BigPipe简介 BigPipe是一个重新设计的基础动态网页服务体系.大体思路是,分解网页成叫做Pagelets的小块,然后通过Web服务器和浏览器建立管道并管理他们在不同阶段的运行.这是类似于 ...

  7. POI导出大量数据的简单解决方案(附源码)-Java-POI导出大量数据,导出Excel文件,压缩ZIP(转载自iteye.com)

    说明:我的电脑 2.0CPU 2G内存 能够十秒钟导出 20W 条数据 ,12.8M的excel内容压缩后2.68M 我们知道在POI导出Excel时,数据量大了,很容易导致内存溢出.由于Excel ...

  8. 【持久化框架】SpringMVC+Spring4+Mybatis3集成,开发简单Web项目+源码下载

    上篇博文我们介绍了mybatis的基本概念与原理,这篇博文我们通过Spring与Mybatis集成,开发一个简单用户增删改查的Web项目. 基本准备工作 1.安装JDK1.6以上版本,安装与配置 2. ...

  9. 3.NetDh框架之缓存操作类和二次开发模式简单设计(附源码和示例代码)

    前言 NetDh框架适用于C/S.B/S的服务端框架,可用于项目开发和学习.目前包含以下四个模块 1.数据库操作层封装Dapper,支持多种数据库类型.多库实例,简单强大: 此部分具体说明可参考博客: ...

随机推荐

  1. Tcl在Vivado中的使用

    http://blog.chinaaet.com/detail/36014 Vivado是Xilinx最新的FPGA设计工具,支持7系列以后的FPGA及Zynq 7000的开发.与之前的ISE设计套件 ...

  2. jquery处理textarea中的手动换行

    textarea的手动换行会产生换行标志,但这个标志存在却看不到,存入数据库中后读出来显示在页面上却不会换行,如何处理呢? 网上众说纷纭,经过测试用 textarea的内容.replace(/\n/g ...

  3. euqals和hashcode

    hashcode这个方法是用来鉴定2个对象是否相等的. 那你会说,不是还有equals这个方法吗? 不错,这2个方法都是用来判断2个对象是否相等的.但是他们是有区别的. 一般来讲,equals这个方法 ...

  4. java中对除法取2位小数的一点试验

    如下程序, double a = 12.3333333,b = 11.22222222222; double c = 0; String d = String.format("%.2f&qu ...

  5. ACM——3n+1

    3n+1 时间限制(普通/Java):1000MS/3000MS          运行内存限制:65536KByte总提交:937            测试通过:386 描述 对于任意大于1的自然 ...

  6. 开源控件ViewPagerIndicator学习

    导航条指示器.ViewPagerIndicator 地址 https://github.com/JakeWharton/ViewPagerIndicator Style是重用控件的一种技术.类似CSS ...

  7. (一)JAVA使用POI操作excel

    1,Poi 简介 Apache POI 是用Java编写的免费开源的跨平台的 Java API,Apache POI提供API给Java程式对Microsoft Office格式档案读和写的功能 PO ...

  8. UIView转场动画属性设置

    常规动画属性设置(可以同时选择多个进行设置) UIViewAnimationOptionLayoutSubviews:动画过程中保证子视图跟随运动. UIViewAnimationOptionAllo ...

  9. objective-c ios webkit 本地存储local-storage

    我有一个Cocoa / Objective-C的应用程序,它嵌入了一个WebKit的web视图.我需要打开的数据库支持和本地存储.我知道这是可以做到-我有它在Safari中工作-但我无法找到如何设置这 ...

  10. 解决读写properties属性文件

    package com.kzkj.wx.utils; import java.io.BufferedReader; import java.io.File; import java.io.FileIn ...