конвертиране на CRC-ITU 16 c код в java

Искам да конвертирам C кодов алгоритъм в Java, за да изчисля CRC. Опитвам се да внедря GPS заключването на BL10 Concox в нашия проект, но не съм сигурен кой байт[] трябва да предам на функцията за изчисляване на CRC. Също така не съм сигурен, че внедряването ми за изчислението на CRC е правилно.

Предавам байт [] от дължина на пакета към сериен номер на информация, както е споменато по-долу.

Проверка за грешки (от „Дължина на пакета“ до „Сериен номер на информация“) са стойности на CRC-ITU. CRC грешка възниква, когато получената информация се изчислява, приемникът ще игнорира и ще отхвърли пакета с данни.

Ето pdf протокола за комуникация:

https://drive.google.com/file/d/1AsBk3iPyLGk4QyuDevYx86lJlfUVYE1t/view

По-долу е C кодът.

C код:

static const U16 crctab16[] ={
0X0000, 0X1189, 0X2312, 0X329B, 0X4624, 0X57AD, 0X6536, 0X74BF,
0X8C48, 0X9DC1, 0XAF5A, 0XBED3, 0XCA6C, 0XDBE5, 0XE97E, 0XF8F7,
 //remove some constant
0XF78F, 0XE606, 0XD49D, 0XC514, 0XB1AB, 0XA022, 0X92B9, 0X8330,
0X7BC7, 0X6A4E, 0X58D5, 0X495C, 0X3DE3, 0X2C6A, 0X1EF1, 0X0F78,
};

// calculate the 16-bit CRC of data with predetermined length.
U16 GetCrc16(const U8* pData, int nLength){
U16 fcs = 0xffff; // initialization
while(nLength>0){
 fcs = (fcs >> 8) ^ crctab16[(fcs ^ *pData) & 0xff];
 nLength--;
 pData++;
} 
 return ~fcs; // negated
}

Досега опитах:

Код на Java:

private static int crctab16[] = { 0X0000, 0X1189, 0X2312, 0X329B, 0X4624, 0X57AD, 0X6536, 0X74BF, 0X8C48, 0X9DC1,
        0XAF5A, 0XBED3, 0XCA6C, 0XDBE5, 0XE97E, 0XF8F7, 0X1081, 0X0108, 0X6306, 0X728F, 0X4014, 0X519D, 0X2522,
        0X34AB, 0X0630, 0X17B9, 0XEF4E, 0XFEC7, 0XCC5C, 0XDDD5, 0XA96A, ....
        0X8B70, 0X8408, 0X9581, 0XA71A, 0XB693, 0XC22C, 0XD3A5, 0XE13E, 
        0XC60C, 0XD785, 0XE51E, 0XF497, 0X8028, 0X91A1, 0XA33A, 0XB2B3, 
        0XB1AB, 0XA022, 0X92B9, 0X8330, 0X7BC7, 0X6A4E, 0X58D5, 0X495C, 0X3DE3, 0X2C6A, 0X1EF1, 0X0F78, };


public static int GetCrc16(final byte[] pData) {
    int crc = 0xffff;// initialization
    for (byte b : pData) {
        crc = (crc >>> 8) ^ crctab16[(crc ^ b) & 0xff];
    }
    return crc; 
}

Проверих резултата чрез това, но не получих правилния резултат.


person Rahul Chavan    schedule 20.04.2018    source източник
comment
Java int и C (наистина псевдоним) U16 са различни типове. Трябва да & 0xffff изчислението (това се прави автоматично на C). Това предотвратява използването на >> върху отрицателни числа   -  person Giacomo Catenazzi    schedule 20.04.2018


Отговори (1)


Вашият return crc; трябва да бъде return crc ^ 0xffff;. Обърнете внимание на ~ в return ~fcs; от C кода. Не отхвърлихте резултата. Той дори предоставя полезния коментар „отхвърлен“.

Можете да използвате ~crc, но тогава ще трябва да направите ~crc & 0xffff, тъй като ints са 32 бита. Така че е по-добре да използвате crc ^ 0xffff.

Не е необходимо да използвате >>> тук. Можете просто да използвате >>, тъй като crc никога няма да бъде отрицателно. И двете са добре.

person Mark Adler    schedule 22.04.2018