Расчет CRC16 - перевод с C на JAVA

В настоящее время я пишу программу JAVA, которая должна отправлять данные в декодер MyLaps через сокет (протокол P3). Двоичные данные должны включать 2-байтовый код CRC. В документации MyLaps есть код на C для вычисления CRC. В нем также говорится, что WORD определен как беззнаковый 16-битный тип.

C-код

    WORD CRC16Table[256] ;
    
    // initialize the CRC16 table
    extern void InitCRC16( void ) {
      WORD i, j ;
      WORD crc ;
      for ( i = 0 ; i < 256 ; i += 1 ) {
        for ( crc = i << 8, j = 0 ; j < 8 ; j += 1 )
          crc = ( crc << 1 ) ^ ( ( crc & 0x8000 ) ? 0x1021 : 0 ) ;
        CRC16Table[ i ] = crc ;
      }
    } 

    // calculate the crc of a char array pointed at by p
    extern WORD CalcCRC16( unsigned char * p, WORD size ) {
      WORD crc = 0xFFFF ;
      WORD i ;
      for ( i = 0 ; i < size ; i++, p++ ) // for all chars
        crc = CRC16Table[ ( ( crc >> 8 ) & 255 ) ] ^ ( crc << 8 ) ^ *p ;
      return crc ;
    }

Я хотел преобразовать этот C-код в код Java. Поскольку java не знает 2-байтового числа без знака, я использовал тип данных char, который также является 2-байтовым.

JAVA-код

    // initialize the CRC16 table
    public static char[] InitCRC16() {
      char i, j;
      char crc;
      char[] CRC16Table = new char[256];
    
      for (i = 0; i < 256; i++) {
        crc = (char) (i << 8);
        for (j = 0; j < 8; j++) {
          crc = (char) ((crc << 1) ^ (((crc & 0x8000) != 0) ? 0x1021 : 0));
        }
        CRC16Table[i] = crc;
      }
      return CRC16Table;
    }
    
    // calculate the crc of a char array        
    public static char CalcCRC16(byte[] p, char[] CRC16Table) {
      char CRC;
      CRC = 0xFFFF;
      for (int ptr = 0; ptr < p.length; ptr++) {
        CRC = (char) (CRC16Table[(( (char) CRC >> 8) & 0xFF)] ^ ((char) CRC << 8) ^ p[ptr]);
      }
      return (char) CRC;
    }

Отправляя данные в декодер MyLaps, я всегда получаю ошибку CRC, поэтому должна быть ошибка при преобразовании кода из C в JAVA.

Кто-нибудь может помочь?

Java знает беззнаковый 16-битный числовой тип. К счастью для вас, это char, который вы выбрали для этой цели.

John Bollinger 22.02.2023 18:38

«Отправляя данные в декодер MyLaps, я всегда получаю ошибку CRC» — вы можете начать с меньшего, сравнив таблицы CRC после инициализации. Они одинаковы?

Ted Lyngmo 22.02.2023 18:42

Это отвечает на ваш вопрос?

Elliott Frisch 22.02.2023 18:48

В общем, для таких вопросов полезно, если вопрос включает примеры (в виде текста) ввода, ожидаемого вывода, фактического вывода (если есть) и фактический текст сообщений об ошибках (если есть). Вы можете отредактировать вопрос.

Old Dog Programmer 22.02.2023 19:07
Как сделать движок для футбольного матча? (простой вариант)
Как сделать движок для футбольного матча? (простой вариант)
Футбол. Для многих людей, живущих на земле, эта игра - больше, чем просто спорт. И эти люди всегда мечтают стать футболистом или менеджером. Но, к...
Знайте свои исключения!
Знайте свои исключения!
В Java исключение - это событие, возникающее во время выполнения программы, которое нарушает нормальный ход выполнения инструкций программы. Когда...
Лучшая компания по разработке спортивных приложений
Лучшая компания по разработке спортивных приложений
Ищете лучшую компанию по разработке спортивных приложений? Этот список, несомненно, облегчит вашу работу!
Blibli Automation Journey - Как захватить сетевой трафик с помощью утилиты HAR в Selenium 4
Blibli Automation Journey - Как захватить сетевой трафик с помощью утилиты HAR в Selenium 4
Если вы являетесь веб-разработчиком или тестировщиком, вы можете быть знакомы с Selenium, популярным инструментом для автоматизации работы...
Фото ️🔁 Radek Jedynak 🔃 on ️🔁 Unsplash 🔃
Фото ️🔁 Radek Jedynak 🔃 on ️🔁 Unsplash 🔃
Что такое Java 8 Streams API? Java 8 Stream API
Деревья поиска (Алгоритм4 Заметки к учебнику)
Деревья поиска (Алгоритм4 Заметки к учебнику)
(1) Двоичные деревья поиска: среднее lgN, наихудшее N для вставки и поиска.
0
4
51
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

В версии для Java происходит много ненужного приведения, что иронично, поскольку проблема, по-видимому, в одном из мест, где вы неправильно адаптируете задействованные преобразования типов.

Учитывая задействованные типы данных, этот код C...

crc = CRC16Table[ ( ( crc >> 8 ) & 255 ) ] ^ ( crc << 8 ) ^ *p ;

... не эквивалентен этому коду Java...

CRC = (char) (CRC16Table[(( (char) CRC >> 8) & 0xFF)] ^ ((char) CRC << 8) ^ p[ptr]);

Вы, кажется, хотите этого:

        CRC = (char) (CRC16Table[(CRC >> 8) & 0xFF] ^ (CRC << 8) ^ (p[ptr] & 0xFF));

Привет Джон, ты мой герой, это было проблемой. Большое спасибо! Пришлось сделать одну небольшую корректировку, вычисление CRC выдало синтаксическую ошибку, пришлось изменить на CRC = (char) (CRC16Table[(CRC >> 8) & 0xFF] ^ (CRC << 8) ^ (p[ptr] & 0xFF)); Oliver

Oliver 22.02.2023 19:36

Я рад, что это помогло, @Oliver, и я отредактировал этот ответ, чтобы устранить описанную вами ошибку.

John Bollinger 22.02.2023 19:39

Другие вопросы по теме