用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

查看:125
本文介绍了用Java中的多项式x ^ 16 + x ^ 12 + x ^ 5 +1计算CCITT标准CRC的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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.

例如,对于此数组[0xFC] [05] [11],结果必须为[27] [56].

For example for this array [0xFC] [05] [11] the result needs to be [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]

I get result FA DE not [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协议的设备进行通讯时,我需要此.

Hope someone can help me. I need this for communication with device using ID003 protocol.

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

Using this online calculator at http://www.lammertbies.nl/comm/info/crc-calculation.html for input FC0511 i get 0x2756 right from CRC-CCITT (Kermit).

推荐答案

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

Here is another version of the Kermit CRC. This one is a direct translation from the C codes in http://www.lammertbies.nl/comm/info/crc-calculation.html. The optimisation is that a table of CRC value for any byte is pre-computed at class loading time, and so the remaining of CRC computations is much simpler.

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

这篇关于用Java中的多项式x ^ 16 + x ^ 12 + x ^ 5 +1计算CCITT标准CRC的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆