Нужна помощь в исправлении ошибок в методе проверки CRC-ITU, написанном на java

Мы пытаемся закодировать прослушиватель устройства GPS на Java.

При этом мы не можем разработать правильный код для проверки ошибок CRC-ITU. Объяснение генерации кода CRC из документа протокола приведено ниже.

Проверочный код может использоваться терминалом или сервером, чтобы определить, является ли полученная информация ошибочной или нет. Чтобы предотвратить ошибки, возникающие во время передачи данных, добавлена ​​​​проверка ошибок против неправильной обработки данных, чтобы повысить безопасность и эффективность системы. Код проверки генерируется методом проверки CRC-ITU. Контрольные коды данных в структуре протокола, от длины пакета до серийного номера информации (включая «Длина пакета» и «Серийный номер информации»), являются значениями CRC-ITU. Если при вычислении полученной информации возникает ошибка CRC, приемник игнорирует и отбрасывает пакет данных.

Это класс прослушивателя данных

      byte[] data = new byte[20];
   System.out.println("Waiting for client on port " + serverSocket.getLocalPort() + "...");
                    Socket server = serverSocket.accept();
                    System.out.println("Just connected to " + server.getRemoteSocketAddress());
                    DataInputStream in = new DataInputStream(server.getInputStream());
                    System.out.println("in = " + in);
                    int packetSize = in.read(data, 0, data.length);
                    StringBuilder sb1 = new StringBuilder();
                    for (byte b : data) {
                        sb1.append(String.format("%02X ", b));
                    }
                    System.out.println("loginpacketHex = " + sb1.toString());
                    for (byte b : data) {
                        System.out.println("loginpacketinbytes = " + b);
                    }
                    NewClass cl = new NewClass();
                    byte[] t = new byte[4];
                    byte[] f = new byte[10];
                    t[0] = 0x05;
                    t[1] = data[3];
                    System.out.println(" t[1] = " + t[1]);
                    t[2] = data[data[2] - 6 + 5];
                    System.out.println("t[2] = " + t[2]);
                    t[3] = data[data[2] - 5 + 5];
                    System.out.println("t[3] = " + t[3]);
                    cl.set(t);
                    short x = cl.get();
                    f[0] = 0x78;
                    f[1] = 0x78;
                    f[2] = 0x05;
                    f[3] = data[3];
                    f[4] = data[data[2] - 6 + 5];
                    f[5] = data[data[2] - 5 + 5];
                    f[6] = (byte) ((x >> 8) & 0xff);
                    f[7] = (byte) (x & 0xff);
                    f[8] = 0x0d;
                    f[9] = 0x0a;

Это класс генерации Crc

public class NewClass {

    public static int crc;

    public static int[] table = {
        0x0000, 0x1189, 0x2312, 0x329B, 0x4624, 0x57AD, 0x6536, 0x74BF,
        0x8C48, 0x9DC1, 0xAF5A, 0xBED3, 0xCA6C, 0xDBE5, 0xE97E, 0xF8F7,
        0x1081, 0x0108, 0x3393, 0x221A, 0x56A5, 0x472C, 0x75B7, 0x643E,
        0x9CC9, 0x8D40, 0xBFDB, 0xAE52, 0xDAED, 0xCB64, 0xF9FF, 0xE876,
        0x2102, 0x308B, 0x0210, 0x1399, 0x6726, 0x76AF, 0x4434, 0x55BD,
        0xAD4A, 0xBCC3, 0x8E58, 0x9FD1, 0xEB6E, 0xFAE7, 0xC87C, 0xD9F5,
        0x3183, 0x200A, 0x1291, 0x0318, 0x77A7, 0x662E, 0x54B5, 0x453C,
        0xBDCB, 0xAC42, 0x9ED9, 0x8F50, 0xFBEF, 0xEA66, 0xD8FD, 0xC974,
        0x4204, 0x538D, 0x6116, 0x709F, 0x0420, 0x15A9, 0x2732, 0x36BB,
        0xCE4C, 0xDFC5, 0xED5E, 0xFCD7, 0x8868, 0x99E1, 0xAB7A, 0xBAF3,
        0x5285, 0x430C, 0x7197, 0x601E, 0x14A1, 0x0528, 0x37B3, 0x263A,
        0xDECD, 0xCF44, 0xFDDF, 0xEC56, 0x98E9, 0x8960, 0xBBFB, 0xAA72,
        0x6306, 0x728F, 0x4014, 0x519D, 0x2522, 0x34AB, 0x0630, 0x17B9,
        0xEF4E, 0xFEC7, 0xCC5C, 0xDDD5, 0xA96A, 0xB8E3, 0x8A78, 0x9BF1,
        0x7387, 0x620E, 0x5095, 0x411C, 0x35A3, 0x242A, 0x16B1, 0x0738,
        0xFFCF, 0xEE46, 0xDCDD, 0xCD54, 0xB9EB, 0xA862, 0x9AF9, 0x8B70,
        0x8408, 0x9581, 0xA71A, 0xB693, 0xC22C, 0xD3A5, 0xE13E, 0xF0B7,
        0x0840, 0x19C9, 0x2B52, 0x3ADB, 0x4E64, 0x5FED, 0x6D76, 0x7CFF,
        0x9489, 0x8500, 0xB79B, 0xA612, 0xD2AD, 0xC324, 0xF1BF, 0xE036,
        0x18C1, 0x0948, 0x3BD3, 0x2A5A, 0x5EE5, 0x4F6C, 0x7DF7, 0x6C7E,
        0xA50A, 0xB483, 0x8618, 0x9791, 0xE32E, 0xF2A7, 0xC03C, 0xD1B5,
        0x2942, 0x38CB, 0x0A50, 0x1BD9, 0x6F66, 0x7EEF, 0x4C74, 0x5DFD,
        0xB58B, 0xA402, 0x9699, 0x8710, 0xF3AF, 0xE226, 0xD0BD, 0xC134,
        0x39C3, 0x284A, 0x1AD1, 0x0B58, 0x7FE7, 0x6E6E, 0x5CF5, 0x4D7C,
        0xC60C, 0xD785, 0xE51E, 0xF497, 0x8028, 0x91A1, 0xA33A, 0xB2B3,
        0x4A44, 0x5BCD, 0x6956, 0x78DF, 0x0C60, 0x1DE9, 0x2F72, 0x3EFB,
        0xD68D, 0xC704, 0xF59F, 0xE416, 0x90A9, 0x8120, 0xB3BB, 0xA232,
        0x5AC5, 0x4B4C, 0x79D7, 0x685E, 0x1CE1, 0x0D68, 0x3FF3, 0x2E7A,
        0xE70E, 0xF687, 0xC41C, 0xD595, 0xA12A, 0xB0A3, 0x8238, 0x93B1,
        0x6B46, 0x7ACF, 0x4854, 0x59DD, 0x2D62, 0x3CEB, 0x0E70, 0x1FF9,
        0xF78F, 0xE606, 0xD49D, 0xC514, 0xB1AB, 0xA022, 0x92B9, 0x8330,
        0x7BC7, 0x6A4E, 0x58D5, 0x495C, 0x3DE3, 0x2C6A, 0x1EF1, 0x0F78,};

    public short get() {
        short c;
        int y;
        y = ~crc;
        c = (short) y;
        return c;
    }

    public void set(byte[] bytes) {
        crc = 0xffff;
        for (byte b : bytes) {
            crc = (crc >>> 8) ^ table[(crc ^ b) & 0xff];
        }
    }

}

Incoming data string comes in following format

    Example of data packet sent by the terminal 78 78 0D 01 01 23 45 67 89 01 23 45 00 01 8C DD 0D 0A

    Explanation

    Start Bit - 0x78 0x78
    Length - 0x0D
    Protocol - 0x01
    Terminal ID - 0x01 0x23 0x45 0x67 0x89 0x01 0x23 0x45
    Serial No - 0x00 0x01
    Error - 0x8C 0xDD
    Stop Bit - 0x0D 0x0A

Я делаю как этот обновленный код.

ByteArrayOutputStream bytearrypacket = new ByteArrayOutputStream();
        DataOutputStream responce = new DataOutputStream(bytearrypacket);
        responce.writeByte(0x0D);
        responce.writeByte(1);
        responce.writeByte(0x03);
        responce.writeByte(0x53);
        responce.writeByte(0x49);
        responce.writeByte(0x20);
        responce.writeByte(0x49);
        responce.writeByte(0x00);
        responce.writeByte(0x05);
        responce.writeByte(0x34);
        responce.writeShort(2);
        NewClass cl = new NewClass();
        cl.set(bytearrypacket.toByteArray());
        System.out.println("cl = " + cl.get());
        System.out.println("hexhexhex = " + Integer.toHexString(cl.get()));
        responce.writeShort(cl.get());

        byte[] res = bytearrypacket.toByteArray();
        for (byte b : res) {
            System.out.println("b = " + b);
        }

person user3920792    schedule 17.09.2014    source источник
comment
Может ли кто-нибудь помочь мне.   -  person user3920792    schedule 17.09.2014
comment
Почти идентичен stackoverflow.com/questions/20870604/ Посмотрите, дает ли алгоритм в версии javascript какие-либо подсказки, как сделать это на Java.   -  person TechTrip    schedule 17.09.2014
comment
В java кто-нибудь может указать на мою ошибку.   -  person user3920792    schedule 17.09.2014
comment
Расчет CRC работает нормально. С какой проблемой вы столкнулись?   -  person Mark Adler    schedule 17.09.2014
comment
я не получаю ответ от устройства   -  person user3920792    schedule 17.09.2014
comment
78 78 05 01 00 01 D9 DC 0D 0A для этого пакета   -  person user3920792    schedule 17.09.2014
comment
CRC в этом пакете, D9 DC, правильный. Ваша проблема в другом.   -  person Mark Adler    schedule 17.09.2014
comment
Не могли бы вы рассказать мне, как вы проверили вывод.   -  person user3920792    schedule 18.09.2014
comment
для меня вывод идет так ffffd9dc   -  person user3920792    schedule 18.09.2014
comment
Я вычислил CRC-16 ITU для 05 01 00 01, и это D9DC. Таким образом, значение проверки пакета правильное.   -  person Mark Adler    schedule 18.09.2014
comment
Метод get() класса NewClass с ужасным названием возвращает short, что составляет 16 бит. Следовательно, это не может быть ffffd9dc. Это может быть только d9dc. ffffd9dc — это то, что вы получите, если присвоите short d9dc int. Знак будет расширен (поскольку в Java есть только целые числа со знаком), что даст вам int с ffffd9dc. Вы можете избавиться от расширения знака с помощью & 0xffff. Или вы можете сохранить его в short, так как он был предоставлен изначально.   -  person Mark Adler    schedule 18.09.2014
comment
Было бы неплохо оставить расширение знака только в int, поскольку доступ к байтам будет осуществляться с помощью (value >> 8) & 0xff и value & 0xff, как в коде вопроса, который также удаляет биты расширения знака.   -  person Mark Adler    schedule 18.09.2014
comment
Я очень извиняюсь за мое плохое имя класса   -  person user3920792    schedule 18.09.2014
comment
78 78 0D 01 03 53 49 20 49 00 05 34 00 02 21 40 0D 0A этот пакет, который я получаю от устройства в этом crc, равен 21 40   -  person user3920792    schedule 18.09.2014
comment
Пожалуйста, посмотрите, что я обновил свой код.   -  person user3920792    schedule 18.09.2014
comment
Для этого пакета я получаю правильный crc, например 2140, а после byteArray я получаю 33 64.   -  person user3920792    schedule 18.09.2014
comment
Но для 78 78 05 01 00 02 D9 DC 0D 0A я получаю -39, -36.   -  person user3920792    schedule 18.09.2014
comment
@ user3920792 извините за опоздание. ты получил ответ?   -  person Rajesh    schedule 04.05.2016


Ответы (1)


Вот код для расчета CRC

открытый класс CRCITUUtil {

private static int[] crcItuTable = {
    0X0000, 0X1189, 0X2312, 0X329B, 0X4624, 0X57AD, 0X6536, 0X74BF,
    0X8C48, 0X9DC1, 0XAF5A, 0XBED3, 0XCA6C, 0XDBE5, 0XE97E, 0XF8F7,
    0X1081, 0X0108, 0X3393, 0X221A, 0X56A5, 0X472C, 0X75B7, 0X643E,
    0X9CC9, 0X8D40, 0XBFDB, 0XAE52, 0XDAED, 0XCB64, 0XF9FF, 0XE876,
    0X2102, 0X308B, 0X0210, 0X1399, 0X6726, 0X76AF, 0X4434, 0X55BD,
    0XAD4A, 0XBCC3, 0X8E58, 0X9FD1, 0XEB6E, 0XFAE7, 0XC87C, 0XD9F5,
    0X3183, 0X200A, 0X1291, 0X0318, 0X77A7, 0X662E, 0X54B5, 0X453C,
    0XBDCB, 0XAC42, 0X9ED9, 0X8F50, 0XFBEF, 0XEA66, 0XD8FD, 0XC974,
    0X4204, 0X538D, 0X6116, 0X709F, 0X0420, 0X15A9, 0X2732, 0X36BB,
    0XCE4C, 0XDFC5, 0XED5E, 0XFCD7, 0X8868, 0X99E1, 0XAB7A, 0XBAF3,
    0X5285, 0X430C, 0X7197, 0X601E, 0X14A1, 0X0528, 0X37B3, 0X263A,
    0XDECD, 0XCF44, 0XFDDF, 0XEC56, 0X98E9, 0X8960, 0XBBFB, 0XAA72,
    0X6306, 0X728F, 0X4014, 0X519D, 0X2522, 0X34AB, 0X0630, 0X17B9,
    0XEF4E, 0XFEC7, 0XCC5C, 0XDDD5, 0XA96A, 0XB8E3, 0X8A78, 0X9BF1,
    0X7387, 0X620E, 0X5095, 0X411C, 0X35A3, 0X242A, 0X16B1, 0X0738,
    0XFFCF, 0XEE46, 0XDCDD, 0XCD54, 0XB9EB, 0XA862, 0X9AF9, 0X8B70,
    0X8408, 0X9581, 0XA71A, 0XB693, 0XC22C, 0XD3A5, 0XE13E, 0XF0B7,
    0X0840, 0X19C9, 0X2B52, 0X3ADB, 0X4E64, 0X5FED, 0X6D76, 0X7CFF,
    0X9489, 0X8500, 0XB79B, 0XA612, 0XD2AD, 0XC324, 0XF1BF, 0XE036,
    0X18C1, 0X0948, 0X3BD3, 0X2A5A, 0X5EE5, 0X4F6C, 0X7DF7, 0X6C7E,
    0XA50A, 0XB483, 0X8618, 0X9791, 0XE32E, 0XF2A7, 0XC03C, 0XD1B5,
    0X2942, 0X38CB, 0X0A50, 0X1BD9, 0X6F66, 0X7EEF, 0X4C74, 0X5DFD,
    0XB58B, 0XA402, 0X9699, 0X8710, 0XF3AF, 0XE226, 0XD0BD, 0XC134,
    0X39C3, 0X284A, 0X1AD1, 0X0B58, 0X7FE7, 0X6E6E, 0X5CF5, 0X4D7C,
    0XC60C, 0XD785, 0XE51E, 0XF497, 0X8028, 0X91A1, 0XA33A, 0XB2B3,
    0X4A44, 0X5BCD, 0X6956, 0X78DF, 0X0C60, 0X1DE9, 0X2F72, 0X3EFB,
    0XD68D, 0XC704, 0XF59F, 0XE416, 0X90A9, 0X8120, 0XB3BB, 0XA232,
    0X5AC5, 0X4B4C, 0X79D7, 0X685E, 0X1CE1, 0X0D68, 0X3FF3, 0X2E7A,
    0XE70E, 0XF687, 0XC41C, 0XD595, 0XA12A, 0XB0A3, 0X8238, 0X93B1,
    0X6B46, 0X7ACF, 0X4854, 0X59DD, 0X2D62, 0X3CEB, 0X0E70, 0X1FF9,
    0XF78F, 0XE606, 0XD49D, 0XC514, 0XB1AB, 0XA022, 0X92B9, 0X8330,
    0X7BC7, 0X6A4E, 0X58D5, 0X495C, 0X3DE3, 0X2C6A, 0X1EF1, 0X0F78,
};

public static byte[] getByteArrayFromInt(int value) {
    byte[] result = new byte[4];
    result[0] = (byte) (value >>> 24);
    result[1] = (byte) (value >>> 16);
    result[2] = (byte) (value >>> 8);
    result[3] = (byte) value;
    return result;
}

public static byte[] getCRCITU(byte[] data) {
    int crc = 0xffff;
    for (byte b : data) {
        crc = (crc >>> 8) ^ crcItuTable[(crc ^ b) & 0xff];
    }
    crc = ~crc;
    return getByteArrayFromInt(crc);
}
public static void main(String[] args) {
    byte[] bytes = CRCITUUtil
            .getCRCITU(new byte[] {0x0D, 0x01, 0x01, 0x23, 0x45, 0x67, (byte) 0x89, 0x01, 0x23, 0x45, 0x00, 0x01});
    System.out.println("CRCUIT:"+ Integer.toHexString(0xff & bytes[2]) + " " +  Integer.toHexString(0xff & bytes[3]));
}

}

Это напечатает

CRCUIT:8c dd
person Solomon Kariri    schedule 06.09.2018