天道酬勤,学无止境

Java中多项式x^16 + x^12 + x^5 + 1计算CCITT标准CRC(Calculation of CCITT standard CRC with polynomial x^16 + x^12 + x^5 + 1 in Java)

问题

我需要在 Java 中使用多项式 x^16 + x^12 + x^5 + 1 (0x1081) 计算 CCITT 标准 CRC 的帮助。 我在互联网上尝试了许多示例,但每个示例都返回示例中的值以外的其他值。

例如,对于这个数组 [0xFC] [05] [11],结果需要是 [27] [56]。

使用此代码:

public static void main(String[] args) {
        byte[] array = new byte[3];
        array[0] = (byte) 0xFC;
        array[1] = (byte) 0x05;
        array[2] = (byte) 0x11;
//        array[3] = (byte) 0x00;
//        array[4] = (byte) 0x00;

        System.out.println(Integer.toHexString(crc16(array)));
    }

    private static final int POLYNOMIAL = 0x1081;
    private static final int PRESET_VALUE = 0xFFFF;

    public static int crc16(byte[] data) {
        int current_crc_value = PRESET_VALUE;
        for (int i = 0; i < data.length; i++) {
            current_crc_value ^= data[i] & 0xFF;
            for (int j = 0; j < 8; j++) {
                if ((current_crc_value & 1) != 0) {
                    current_crc_value = (current_crc_value >>> 1) ^ POLYNOMIAL;
                } else {
                    current_crc_value = current_crc_value >>> 1;
                }
            }
        }
        current_crc_value = ~current_crc_value;

        return current_crc_value & 0xFFFF;
    } 

我得到的结果不是FA DE [27] [56]

使用此代码:

public static void main(String[] args) { 
        int crc = 0x0000;         
        int polynomial = 0x1081;   

        // byte[] testBytes = "123456789".getBytes("ASCII");

//        byte[] array = args[0].getBytes();
        byte[] array = new byte[3];
        array[0] = (byte) 0xFC;
        array[1] = (byte) 0x05;
        array[2] = (byte) 0x11;

        for (byte b : array) {
            for (int i = 0; i < 8; i++) {
                boolean bit = ((b   >> (7-i) & 1) == 1);
                boolean c15 = ((crc >> 15    & 1) == 1);
                crc <<= 1;
                if (c15 ^ bit) crc ^= polynomial;
             }
        }

        crc &= 0xffff;
        System.out.println("CRC16-CCITT = " + Integer.toHexString(crc));
    }

我得到这个CRC16-CCITT = 8dca

使用此代码:

private final int polynomial = 0x1081;

    private int[] table = new int[256];

    public int ComputeChecksum(int[] bytes) {
        int crc = 0xffff;
        for (int i = 0; i < bytes.length; ++i) {
            int index = (crc ^ bytes[i]) % 256;
            crc = (crc >> 8) ^ table[index];
        }
        return crc;
    }

    public CRC162() {
        int value;
        int temp;
        for (int i = 0; i < table.length; ++i) {
            value = 0;
            temp = i;
            for (byte j = 0; j < 8; ++j) {
                if (((value ^ temp) & 0x0001) != 0) {
                    value = (value >> 1) ^ polynomial;
                } else {
                    value >>= 1;
                }
                temp >>= 1;
            }
            table[i] = value;
        }
    }

    public static void main(String[] args) {
        CRC162 c = new CRC162();
        int[] arr = new int[]{0xFC, 0x05, 0x11};
        System.out.println(Integer.toHexString(c.ComputeChecksum(arr)));
    }

我得到这个521

希望可以有人帮帮我。 我需要它来与使用 ID003 协议的设备进行通信。

编辑:使用 http://www.lammertbies.nl/comm/info/crc-calculation.html 上的这个在线计算器输入 FC0511 我从 CRC-CCITT (Kermit) 得到 0x2756。

回答1

这是 Kermit CRC 的另一个版本。 这是 http://www.lammertbies.nl/comm/info/crc-calculation.html 中的 C 代码的直接翻译。 优化是在类加载时预先计算任何字节的CRC值表,因此剩余的CRC计算要简单得多。

public class Crc {

    private static final int POLYNOMIAL = 0x8408;
    private static final int PRESET = 0;
    static private int[] tab;

    static {
        tab = new int[256];
        for (int i = 0; i < 256; i++) {
            tab[i] = initial((byte) i);
        }
    }

    private static int initial(byte c) {
        int crc = 0;
        for (int j = 0; j < 8; j++) {
            if (((crc ^ c) & 1) == 1) {
                crc = ((crc >> 1) ^ POLYNOMIAL);
            } else {
                crc = (crc >> 1);
            }
            c = (byte) (c >> 1);
        }
        return crc;
    }

    private static int update_crc(int crc, byte c) {
        int cc = (0xff & c);

        int tmp = (crc ^ cc);
        crc = (crc >> 8) ^ tab[tmp & 0xff];

        return crc;
    }

    private static int swab(int n) {
        return (((n & 0xFF00) >> 8) + ((n & 0xFF) << 8));
    }

    public static int crc(String str) {
        return crcb(str.getBytes());
    }

    public static int crcb(byte... i) {
        int crc = PRESET;
        for (byte c : i) {
            crc = update_crc(crc, c);
        }
        return swab(crc);
    }

    public static void main(String[] args) {
        int crc = Crc.crcb((byte) 0xFC, (byte) 5, (byte) 0x11);
        System.out.println(Integer.toHexString(crc));
        crc = Crc.crc("123456789");
        System.out.println(Integer.toHexString(crc));
    }
}

输出符合预期:

2756
8921
回答2

x^16 + x^12 + x^5 + 1 不是 0x1081。 它是 0x1021。 x^5 是 20,而不是 80。(注意 x^16 被删除。)

此外,您需要的 Kermit CRC 被反映,因此多项式被反转给出 0x8408。

对于此 CRC,您用零初始化并且不对结果进行补码。

因此,相应地修改您的第一个示例,这将计算您想要的内容:

public static void main(String[] args) {
    byte[] array = new byte[3];
    array[0] = (byte) 0xFC;
    array[1] = (byte) 0x05;
    array[2] = (byte) 0x11;
    //        array[3] = (byte) 0x00;
    //        array[4] = (byte) 0x00;

    System.out.println(Integer.toHexString(crc16(array)));
}

private static final int POLYNOMIAL = 0x8408;
private static final int PRESET_VALUE = 0;

public static int crc16(byte[] data) {
    int current_crc_value = PRESET_VALUE;
    for (int i = 0; i < data.length; i++) {
        current_crc_value ^= data[i] & 0xFF;
        for (int j = 0; j < 8; j++) {
            if ((current_crc_value & 1) != 0) {
                current_crc_value = (current_crc_value >>> 1) ^ POLYNOMIAL;
            } else {
                current_crc_value = current_crc_value >>> 1;
            }
        }
    }

    return current_crc_value & 0xFFFF;
}
回答3

这不是我的,但对我来说很完美,“DatatypeConverter”是我在我的项目中已经拥有的东西。 这对我来说是一个真实的例子并且有效。

*  Reads in a sequence of bytes and prints out its 16 bit
*  Cylcic Redundancy Check (CRC-CCIIT 0xFFFF).
*
*  1 + x + x^5 + x^12 + x^16 is irreducible polynomial.

import javax.xml.bind.DatatypeConverter;

public class CRC16CCITT {

    public static void main(String[] args) {
        int crc = 0xFFFF; // initial value
        int polynomial = 0x1021; // 0001 0000 0010 0001 (0, 5, 12), in your case: 0x1081

        // CRC of this should be 28570
        byte[] testBytes = DatatypeConverter.parseHexBinary("00000000000000000000FA00000002009F1D19B87475445E1122330000000000"); 

        for (byte b : testBytes) {
            for (int i = 0; i < 8; i++) {
                boolean bit = ((b >> (7 - i) & 1) == 1);
                boolean c15 = ((crc >> 15 & 1) == 1);
                crc <<= 1;
                if (c15 ^ bit)
                    crc ^= polynomial;
            }
        }

        crc &= 0xffff;
        System.out.println("CRC16-CCITT = " + Integer.toHexString(crc));
        // 6F9A = 28570
    }

}
回答4
    /**
 * converts the given String to CRC16
 * 
 * @param inputStr
 *            - the input string to get the CRC
 * @param polynomial
 *            - the polynomial (divisor)
 * @param crc
 *            - the CRC mask
 * @param isHex
 *            - if true, treat input string as hex, otherwise, treat as
 *            ASCII
 * @return
 */
public static String getCRC16CCITT(String inputStr, int polynomial,
        int crc, boolean isHex) {

    int strLen = inputStr.length();     
    int[] intArray;

    if (isHex) {
        if (strLen % 2 != 0) {
            inputStr = inputStr.substring(0, strLen - 1) + "0"
                    + inputStr.substring(strLen - 1, strLen);
            strLen++;
        }

        intArray = new int[strLen / 2];
        int ctr = 0;
        for (int n = 0; n < strLen; n += 2) {
            intArray[ctr] = Integer.valueOf(inputStr.substring(n, n + 2), 16);
            ctr++;
        }
    } else {
        intArray = new int[inputStr.getBytes().length];
        int ctr=0;
        for(byte b : inputStr.getBytes()){
            intArray[ctr] = b;
            ctr++;
        }
    }

    // main code for computing the 16-bit CRC-CCITT
    for (int b : intArray) {
        for (int i = 0; i < 8; i++) {
            boolean bit = ((b >> (7 - i) & 1) == 1);
            boolean c15 = ((crc >> 15 & 1) == 1);
            crc <<= 1;
            if (c15 ^ bit)
                crc ^= polynomial;
        }
    }

    crc &= 0xFFFF;
    return Integer.toHexString(crc).toUpperCase();
}

适用于 ASCII 和 HEX 计算。

public static void main(String args[]) {

    String testStr = "9142656";

    // XModem ASCII
    System.out.println("CRC-CCITT (XModem) Ascii: "
            + getCRC16CCITT(testStr, 0x1021, 0x0000, false));

    // 0xFFFF ASCII
    System.out.println("CRC-CCITT (0xFFFF) Ascii: "
            + getCRC16CCITT(testStr, 0x1021, 0xFFFF, false));

    // 0x1D0F ASCII
    System.out.println("CRC-CCITT (0x1D0F) Ascii: "
            + getCRC16CCITT(testStr, 0x1021, 0x1D0F, false));

    // XModem Hex
    System.out.println("CRC-CCITT (XModem) Hex: "
            + getCRC16CCITT(testStr, 0x1021, 0x0000, true));

    // 0xFFFF Hex
    System.out.println("CRC-CCITT (0xFFFF) Hex: "
            + getCRC16CCITT(testStr, 0x1021, 0xFFFF, true));

    // 0x1D0F Hex
    System.out.println("CRC-CCITT (0x1D0F) Hex: "
            + getCRC16CCITT(testStr, 0x1021, 0x1D0F, true));

}

输出:

CRC-CCITT (XModem) Ascii: 87F4
CRC-CCITT (0xFFFF) ASCII:763A
CRC-CCITT (0x1D0F) ASCII:9F86
CRC-CCITT (XModem) 十六进制:57FF
CRC-CCITT (0xFFFF) 十六进制:D33F
CRC-CCITT (0x1D0F) 十六进制:59EF

解决方案基于普林斯顿大学 http://introcs.cs.princeton.edu/java/61data/CRC16CCITT.java 中的示例

受限制的 HTML

  • 允许的HTML标签:<a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • 自动断行和分段。
  • 网页和电子邮件地址自动转换为链接。

相关推荐
  • 如何配置CRC表的计算(How to configure calculation of CRC table)
    问题 那里有很多CRC计算示例。 带有位移的简单实现,并通过预先计算的表更有效。 但是多项式旁边还有很多CRC参数会影响计算。 您可以在此处评估这些参数:http://zorc.breitbandkatze.de/crc.html 这些参数是 CRC的初始值输入数据的反映反映输出数据 CRC的最终XOR值 对于某些“标准” CRC算法,这些参数已很好定义,例如CRC-16(CCITT)。 但是有些实现使用不同的参数。 我的实现必须与CCITT多项式(x 16 + x 12 + x 5 +1)的CRC16兼容。 但是必须反映数据字节和最终的CRC。 我已经在计算方法中实现了这些反射。 但这很耗时。 为了获得最佳性能,必须将其从计算中删除。 在初始化方法中如何计算CRC的反射参数? 编辑:我应该怎么做才能分别控制每个参数? 我想了解Init函数的实际工作方式以及所有参数的实现方式。 typedef unsigned char uint8_t; typedef unsigned short crc; crc crcTable[256]; #define WIDTH (8 * sizeof(crc)) #define TOPBIT (1 << (WIDTH - 1)) #define POLYNOMIAL 0x1021 template<typename t> t reflect(t v)
  • Calculation of CCITT standard CRC with polynomial x^16 + x^12 + x^5 + 1 in Java
    I need help with calculating of CCITT standard CRC with polynomial x^16 + x^12 + x^5 + 1 (0x1081) in Java. I have tried many examples on the internet but every one of them returns other values than the ones in the example. For example for this array [0xFC] [05] [11] the result needs to be [27] [56]. Using this code: public static void main(String[] args) { byte[] array = new byte[3]; array[0] = (byte) 0xFC; array[1] = (byte) 0x05; array[2] = (byte) 0x11; // array[3] = (byte) 0x00; // array[4] = (byte) 0x00; System.out.println(Integer.toHexString(crc16(array))); } private static final int
  • 如何在 PHP HEX 中计算 CRC16 CCITT?(How to calculate CRC16 CCITT in PHP HEX?)
    问题 我正在尝试使用 PHP CRC16 CCITT 函数来计算校验和。 设备向我发送了一个包含校验和的 PACKET: 10 00 00 00 00 00 00 00 12 51 09 08 00 18 00 04 02 14 00 0c 00 0c 02 1c 00 02 00 00 00 00 00 7 00 a 0 校验和在最后: a0 77 我试过使用 如何在php中计算crc16 为 CRC16 函数将 C 转换为 PHP 没有成功,CRC 16 计算返回: E6 F4而不是a0 77 查找时,我返回了正确的十六进制信息: 100000000000000012510908001800040214000c000c021c0002000000000000 在网站 http://www.lammertbies.nl/comm/info/crc-calculation.html 上,但我无法重现它。 (确保选择输入类型为HEX) 你能帮我弄清楚如何获得十六进制值字符串的 crc16 CCITT 100000000000000012510908001800040214000c000c021c0002000000000000 我正在寻找校验和a0 77 回答1 我能够使用如下实现生成相同的校验和: define('CRC16POLYN', 0x1021); function
  • CCITT CRC 16 位起始值 0xffff(CCITT CRC 16 Bit Start Value 0xffff)
    问题 我需要计算作为参数与长度一起传递的数据的 CCITT 16 位校验和值。 如果我用测试数据“123456789”填充我的数组 TempStr,使用长度不包括空终止字符的多项式 0x8408,我得到结果字符串 6E90(Hex)。 连同空终止字符,我得到 907A。 当我将多项式交换为 0x1201 时,我会得到带有和不带有终止符的结果 29E2(Hex) 和 EFE8(Hex)。 我的问题是:我是否需要计算带有或不带有空终止符的 CRC 以获得正确的值? 我在算法中使用多项式 0x1201 还是逆多项式 0x8408? 给定数据 0x29B1 的 CRC 是否正确? 我需要正确的值来确定函数是否正常工作。计算此特定 CRC 类型的算法是否正确? wData=(unsigned int)0xff & *pData++?? 如果有人可以向我解释出了什么问题以及如何解决我的问题,我将不胜感激。 谢谢 这是使用和显示 calculate_CRC16 函数的代码: CHAR_t TestStr[] = {"123456789"}; unsigned short CrcTest = calculate_CRC16(TestStr,sizeof(TestStr)-1); QString CrcDisplay = QString("CrcTest : %1").arg(CrcTest)
  • 纠错码CRC详细计算(精华)
    1. CRC CRC(Cyclic Redundancy Check)循环冗余校验码,是常用的校验码.对通信的可靠性检查就需要‘校验’,校验是从数据本身进行检查,它依靠某种数学上约定的形式进行检查,校验的结果是可靠或不可靠,如果可靠就对数据进行处理,如果不可靠,就丢弃重发或者进行修复。 CRC码是由两部分组成,前部分是信息码,就是需要校验的信息,后部分是校验码,如果CRC码共长n个bit,信息码长k个bit,就称为(n,k)码。 它的编码规则是: 1、首先将原信息码(kbit)左移r位(k+r=n) 2、运用一个生成多项式g(x)(也可看成二进制数,是事先定义好了的)用模2除上面的式子,得到的余数就是校验码。3.多项式的二进制数位数是r(原信息的左移位)+1位. 非常简单,要说明的:模2除就是在除的过程中用模2加,模2加实际上就是我们熟悉的异或运算,就是加法不考虑进位,公式是: 0+0=1+1=0,1+0=0+1=1即‘异’则真,‘非异’则假。 有了加法就可以用来定义模2除法,于是就可以用生成多项式g(x)生成CRC校验码。例如: g(x)=X4+X3+X2+1,(7,3)码,信息码110产生的CRC码就是: 101 商11101 | 1100000 11101 10100 11101 1001 余数余数是1001,所以CRC码是110,1001标准的CRC码是,CRC
  • C的确定性CRC(definitive CRC for C)
    问题 由于CRC的使用如此广泛,因此我很难在C中找到CRC实现感到惊讶。 是否有“所有人”使用的C的“确定的” CRC计算代码段/算法? 或者:有人可以担保并提出我一个好的CRC实施方案吗? 我特别在寻找CRC8和CRC16实现。 想到这一点,我的情况可能有点不合常规。 我正在为Linux编写C代码,并且该代码最终应移植到微控制器上。 似乎某些微控制器API确实与CRC实现一起提供。 无论如何,我都在寻找通用的软件实现(我读到CRC最初是由硬件实现的)。 回答1 不会。因为“ CRC”代表一组基于多项式的算法,所以没有“确定的CRC”。 通常会根据大小给出各种[模糊]通用名称(例如CRC-8,CRC-32)。 不幸的是,大多数尺寸都有几种不同的版本。 维基百科的“循环冗余校验”条目列出了一些常见的变体,但是必须使用给定域的正确校验和,否则会出现不兼容性。 (请参阅我对迈克答案的评论,以了解这有多令人困惑!) 无论如何,选择一个合适的实现并使用它-在网上可以找到很多示例。 如果碰巧有一个提供适当实现的库,则一定要使用它。 但是,没有为此的“标准” C库。 这里有一些资源: 在AutomationWiki上的“ CRC16”(CRC-16-CCITT)实现。 对Dobbs博士实施CCITT循环冗余检查。 Chris Borrelli撰写的IEEE 802
  • CRC16算法之二:CRC16-CCITT-XMODEM算法的java实现
    CRC16算法系列文章: CRC16算法之一:CRC16-CCITT-FALSE算法的java实现 CRC16算法之二:CRC16-CCITT-XMODEM算法的java实现 CRC16算法之三:CRC16-CCITT-MODBUS算法的java实现 前言CRC16算法有很多种,本篇文章会介绍其中的CRC16-CCITT-XMODEM算法 功能实现CRC16-CCITT-XMODEM算法支持int、short类型支持选择数组区域计算实现package cc.eguid.crc16; /** * crc16多项式算法 * @author eguid * */public class CRC16 { /** * CRC16-XMODEM算法(四字节) * @param bytes * @return */public static int crc16_ccitt_xmodem(byte[] bytes) {return crc16_ccitt_xmodem(bytes,0,bytes.length);} /** * CRC16-XMODEM算法(四字节) * @param bytes * @param offset * @param count * @return */public static int crc16_ccitt_xmodem(byte[] bytes,int
  • CRC16算法之二:CRC16-CCITT-XMODEM算法的java实现
    CRC16算法系列文章:CRC16算法之一:CRC16-CCITT-FALSE算法的java实现 CRC16算法之二:CRC16-CCITT-XMODEM算法的java实现 CRC16算法之三:CRC16-CCITT-MODBUS算法的java实现 前言CRC16算法有很多种,本篇文章会介绍其中的CRC16-CCITT-XMODEM算法 功能实现CRC16-CCITT-XMODEM算法支持int、short类型支持选择数组区域计算实现package cc.eguid.crc16; /** * crc16多项式算法 * @author eguid * */ public class CRC16 { /** * CRC16-XMODEM算法(四字节) * @param bytes * @return */ public static int crc16_ccitt_xmodem(byte[] bytes) { return crc16_ccitt_xmodem(bytes,0,bytes.length); } /** * CRC16-XMODEM算法(四字节) * @param bytes * @param offset * @param count * @return */ public static int crc16_ccitt_xmodem(byte[] bytes,int
  • CRC16算法之一:CRC16-CCITT-FALSE算法的java实现
    CRC16算法系列文章: CRC16算法之一:CRC16-CCITT-FALSE算法的java实现 CRC16算法之二:CRC16-CCITT-XMODEM算法的java实现 CRC16算法之三:CRC16-CCITT-MODBUS算法的java实现 前言 JDK里包含了CRC32的算法,但是没有CRC16的,网上搜了一堆没有找到想要的,索性自己实现注意:CRC16算法分为很多种,本篇文章中,只讲其中的一种:CRC16-CCITT-FALSE算法CRC16算法系列之一:CRC16-CCITT-FALSE算法的java实现功能1、支持short类型2、支持int类型3、支持数组任意区域计算实现/** * crc16-ccitt-false加密工具 * * @author eguid * */ public class CRC16 { /** * crc16-ccitt-false加/解密(四字节) * * @param bytes * @return */ public static int crc16(byte[] bytes) { return crc16(bytes, bytes.length); } /** * crc16-ccitt-false加/解密(四字节) * * @param bytes -字节数组 * @return */ public static int
  • 最通俗的CRC校验原理剖析
    以下内容摘自笔者即将出版的最新著作《深入理解计算机网络》一书。本书将于12月底出版上市,敬请留意!! 本书原始目录参见此文:http://winda.blog.51cto.com/55153/1063878 5.3.2 循环冗余校验检错方案 上节介绍的奇偶校验码(PCC)只能校验一位错误,本节所要介绍的循环冗余校验码(CRC)的检错能力更强,可以检出多位错误。 1. CRC校验原理 CRC校验原理看起来比较复杂,好难懂,因为大多数书上基本上是以二进制的多项式形式来说明的。其实很简单的问题,其根本思想就是先在要发送的帧后面附加一个数(这个就是用来校验的校验码,但要注意,这里的数也是二进制序列的,下同),生成一个新帧发送给接收端。当然,这个附加的数不是随意的,它要使所生成的新帧能与发送端和接收端共同选定的某个特定数整除(注意,这里不是直接采用二进制除法,而是采用一种称之为“模2除法”)。到达接收端后,再把接收到的新帧除以(同样采用“模2除法”)这个选定的除数。因为在发送端发送数据帧之前就已通过附加一个数,做了“去余”处理(也就已经能整除了),所以结果应该是没有余数。如果有余数,则表明该帧在传输过程中出现了差错。 【说明】“模2除法”与“算术除法”类似,但它既不向上位借位,也不比较除数和被除数的相同位数值的大小,只要以相同位数进行相除即可。模2加法运算为:1+1=0,0+1=1,0+0
  • 循环冗余码校验
    循环冗余码校验(Cyclic Redundancy Check) 5.3.2 循环冗余校验检错方案 上节介绍的奇偶校验码(PCC)只能校验一位错误,本节所要介绍的循环冗余校验码(CRC)的检错能力更强,可以检出多位错误。 1. CRC校验原理 CRC校验原理看起来比较复杂,好难懂,因为大多数书上基本上是以二进制的多项式形式来说明的。其实很简单的问题,其根本思想就是先在要发送的帧后面附加一个数(这个就是用来校验的校验码,但要注意,这里的数也是二进制序列的,下同),生成一个新帧发送给接收端。当然,这个附加的数不是随意的,它要使所生成的新帧能与发送端和接收端共同选定的某个特定数整除(注意,这里不是直接采用二进制除法,而是采用一种称之为"模 2 除法 ")。到达接收端后,再把接收到的新帧除以(同样采用"模2除法")这个选定的除数。因为在发送端发送数据帧之前就已通过附加一个数,做了"去余"处理(也就已经能整除了),所以结果应该是没有余数。如果有余数,则表明该帧在传输过程中出现了差错。 【说明】"模2除法"与"算术除法"类似,但它既不向上位借位,也不比较除数和被除数的相同位数值的大小,只要以相同位数进行相除即可。模2加法运算为:1+1=0,0+1=1,0+0=0,无进位,也无借位;模2减法运算为:1-1=0,0-1=1,1-0=1,0-0=0,也无进位,无借位。相当于二进制中的逻辑异或运算
  • CRC通用计算类
    /*前段时间在做项目中用到了CRC循环校验,在网上查了很多资料,但是都很零乱;本人作了相关整理,并对常用的循环冗余校验进行了封装,形成本文件。在这里感谢网络上提供相关资料的朋友们,关于他们的名字在这里我无法一一列举,再次向他们表示感谢!*/ /*以下代码的计算思想适用于所有CRC校验算法。64位以上的由于ulong已经无法表示了,所以没有实现。但是思想也是一样的。不过64位以上可以使用.net里面的别的hash:比如md5等算法.主要参考地址:[url]http://www.wiki.cn/wiki/Cyclic_redundancy_check[/url][url]http://www.zorc.breitbandkatze.de/crc.html[/url] [url]http://www.zorc.breitbandkatze.de/crctester.c[/url]*/ /*需要注意的是:即使都是同样位数的crc校验,多项式也可以不同。即使多项式相同,初值,末值xor,是否反转等设置也可以不同所以在通信的双方需要约定好。以下的具体crc子类只是我能找到的一些常用的crc约定。哪位兄弟有具体的crc约定,可以告知我进行扩展。*/ //* 采用了泛型定义基类,基类是一个通用的计算CRC的方法,定义具体的类时只需要设置好CRC设置即可。//* 本来想用c#写模版代码,可是C
  • CRC16算法之一:CRC16-CCITT-FALSE算法的java实现
    CRC16算法系列文章: CRC16算法之一:CRC16-CCITT-FALSE算法的java实现 CRC16算法之二:CRC16-CCITT-XMODEM算法的java实现 CRC16算法之三:CRC16-CCITT-MODBUS算法的java实现 前言JDK里包含了CRC32的算法,但是没有CRC16的,网上搜了一堆没有找到想要的,索性自己实现注意:CRC16算法分为很多种,本篇文章中,只讲其中的一种:CRC16-CCITT-FALSE算法CRC16算法系列之一:CRC16-CCITT-FALSE算法的java实现功能1、支持short类型2、支持int类型3、支持数组任意区域计算实现/** * crc16-ccitt-false加密工具 * * @author eguid * */public class CRC16 { /** * crc16-ccitt-false加/解密(四字节) * * @param bytes * @return */public static int crc16(byte[] bytes) {return crc16(bytes, bytes.length); } /** * crc16-ccitt-false加/解密(四字节) * * @param bytes -字节数组 * @return */public static int crc16
  • CRC-CCITT (0xFFFF) function?
    Can someone help me with Delphi implementation of CRC-CCITT (0xFFFF)? Already get the Java version, but confusing on how to port it to Delphi public static int CRC16CCITT(byte[] bytes) { int crc = 0xFFFF; // initial value int polynomial = 0x1021; // 0001 0000 0010 0001 (0, 5, 12) for (byte b : bytes) { for (int i = 0; i < 8; i++) { boolean bit = ((b >> (7-i) & 1) == 1); boolean c15 = ((crc >> 15 & 1) == 1); crc <<= 1; if (c15 ^ bit) crc ^= polynomial; } } crc &= 0xffff; //System.out.println("CRC16-CCITT = " + Integer.toHexString(crc)); return crc; } and for PHP implementation <?php function
  • CRC-CCITT 到 CRC16 Modbus 实现(CRC-CCITT to CRC16 Modbus implementation)
    问题 我在使用 PHP 生成 modbus CRC16 代码时遇到了很多麻烦。 我在互联网上找到了很多不同的代码,但我已经尝试过,但由于某种原因我没有得到正确的结果。 我找到了一个用于生成 CRC16-CCITT 的 PHP 代码。 我已将查找表更改为 modbus CRC 对应表,但结果仍然不正确。 代码如下。 我还需要做什么才能将 CRC16-CCITT 代码转换为 CRC16-MODBUS 代码。 <?php /************************************************************************* * phpCrc16 v1.1 -- CRC16/CCITT implementation * * By Matteo Beccati <matteo@beccati.com> * * Original code by: * Ashley Roll * Digital Nemesis Pty Ltd * www.digitalnemesis.com * ash@digitalnemesis.com * * Test Vector: "123456789" (character string, no quotes) * Generated CRC: 0x29B1 * *****************************
  • CRC16算法之三:CRC16-CCITT-MODBUS算法的java实现
    CRC16算法系列文章:CRC16算法之一:CRC16-CCITT-FALSE算法的java实现 CRC16算法之二:CRC16-CCITT-XMODEM算法的java实现 CRC16算法之三:CRC16-CCITT-MODBUS算法的java实现 功能 实现CRC16-CCITT-MODBUS算法支持int、short类型支持选择数组区域计算实现 /** * crc16_ccitt_modbus算法(四字节)友情提示:做好自己!--eguid博客地址:http://blog.csdn.net/eguid_1 * @param buf * @param offset * @param length * @return */ public static int crc16_ccitt_modbus(byte[] buf,int offset, int length) { int i, j; int c, crc = 0xFFFF; for (i = offset; i < length; i++) { c = buf[i] & 0x00FF; crc ^= c; for (j = 0; j < 8; j++) { if ((crc & 0x0001) != 0) { crc >>= 1; crc ^= 0xA001; } else crc >>= 1; } } return crc
  • CRC16算法之三:CRC16-CCITT-MODBUS算法的java实现
    CRC16算法系列文章: CRC16算法之一:CRC16-CCITT-FALSE算法的java实现 CRC16算法之二:CRC16-CCITT-XMODEM算法的java实现 CRC16算法之三:CRC16-CCITT-MODBUS算法的java实现 功能实现CRC16-CCITT-MODBUS算法支持int、short类型支持选择数组区域计算实现/** * crc16_ccitt_modbus算法(四字节)友情提示:做好自己!--eguid博客地址:http://blog.csdn.net/eguid_1 * @param buf * @param offset * @param length * @return */public static int crc16_ccitt_modbus(byte[] buf,int offset, int length) {int i, j;int c, crc = 0xFFFF;for (i = offset; i < length; i++) {c = buf[i] & 0x00FF;crc ^= c;for (j = 0; j < 8; j++) {if ((crc & 0x0001) != 0) {crc >>= 1;crc ^= 0xA001;} elsecrc >>= 1;}}return crc;} /** * crc16
  • How to configure calculation of CRC table
    There are a lot of CRC calculation examples out there. Simple implementations with bit shifting and more efficient with a pre-calculated table. But there are also a lot of Parameters of a CRC beside the polynomial that affect the calculation. You can evaluate these parameters here: http://zorc.breitbandkatze.de/crc.html These parameters are initial value of CRC reflection of input data reflection of output data final XOR value for CRC For some "standard" CRC algorithm these parameters are well defined, like CRC-16 (CCITT). But there are some implementations that use different parameters. My
  • CRC16查表法校验编程
    CRC校验 循环冗余校验,是一种数据传输检错功能,对数据进行多项式计算,并将校验结果附在帧后面,生成一个新帧发送给通讯设备。 CRC16多项式:x16+x15+x2+1 CRC16校验表:CRC-CCITT using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Collections; namespace Crc_Eg { class Program { public static UInt16 CRC16_INIT_VAL = 0x0000; //CRC16静态表 public static UInt16[] Crc16Table = new UInt16[256]{0x0000,0x1021,0x2042,0x3063,0x4084,0x50a5,0x60c6,0x70e7, 0x8108,0x9129,0xa14a,0xb16b,0xc18c,0xd1ad,0xe1ce,0xf1ef, 0x1231,0x0210,0x3273,0x2252,0x52b5,0x4294,0x72f7,0x62d6, 0x9339,0x8318,0xb37b,0xa35a,0xd3bd
  • 我如何猜测校验和算法?(How could I guess a checksum algorithm?)
    问题 假设我有一些数据包的末尾带有16位校验和。 我想猜测使用哪种校验和算法。 首先,从转储数据中,我可以看到数据包有效负载中的一个字节变化完全改变了校验和,因此我可以假定它不是某种简单的XOR或求和。 然后,我尝试了几种CRC16的变体,但运气不佳。 这个问题可能更偏向于密码学,但是我对任何易于理解的统计工具来找出这可能是CRC感兴趣。 如果其他所有方法都失败了,我什至可以转向绘制不同的CRC算法。 背景故事:我有带有某种校验和的串行RFID协议。 我可以毫无问题地重放消息,并解释结果(不进行校验和检查),但是由于设备将其丢在了地板上,所以我无法发送修改后的数据包。 使用现有软件,我可以更改RFID芯片的有效载荷。 但是,唯一的序列号是不可变的,因此我无法检查所有可能的组合。 尽管我可以生成递增1的值的转储,但不足以使详尽搜索适用于此问题。 如果问题本身还不够,则可以使用带有数据的转储文件:-) 需要参考文件吗? CRC错误检测算法的无忧指南是很好的参考,我在这里提出问题后就找到了。 最后,在给出了可接受的答案(比CCITT有用的提示)之后,我使用了此CRC计算器,并将生成的校验和与已知的校验和进行异或运算,得到0xffff,这使我得出结论:最终的xor是CCITT的0x0000的instread的0xffff。 回答1 CRC有很多变量需要考虑: Polynomial No