2015-05-05 9 views
-1

У меня есть источник с контрольной суммой CRC16 в C++:Контрольная сумма CRC 16 с C++ на Java

quint16 MainWindow::calculateCRC16(QByteArray buffer) 
{ 
    quint16 newCrc; 
    quint8 i; 
    newCrc = 0xFFFF; 

    for(i = 0; i < buffer.size(); i++){ 
     newCrc = this->crc16_update(newCrc, (quint8)buffer.at(i)); 
    } 
    return newCrc; 
} 

quint16 MainWindow::crc16_update(quint16 crc, quint8 a) 
{ 
    quint8 i; 

    crc ^= a; 

    for (i = 0; i < 8; ++i) { 
     if (crc & 1) 
      crc = (crc >> 1)^0xA001; 
     else 
      crc = (crc >> 1); 
    } 
    return crc; 
} 

Например, когда мы помещаем:

QByteArray buffer = \x02\x14\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00

Результат:

int result = 65535 
QByteArray result = \x1d\x20 

Я попытался добиться такого же результата на Java, но без положительного эффекта

Первый пример:

int calculate_crc(byte[] bytes) { 
    int i; 
    int crc_value = 0; 
    for (int len = 0; len < bytes.length; len++) { 
     for (i = 0x80; i != 0; i >>= 1) { 
      if ((crc_value & 0x8000) != 0) { 
       crc_value = (crc_value << 1)^0x8005; 
      } else { 
       crc_value = crc_value << 1; 
      } 
      if ((bytes[len] & i) != 0) { 
       crc_value ^= 0x8005; 
      } 
     } 
    } 
    return crc_value; 
} 

Другое один:

private int calculateCRC16(byte[] buffer) 
{ 
    int newCrc; 
    int i; 
    newCrc = 0xFFFF; 
    for(i = 0; i < buffer.length; i++) { 
     newCrc = this.crc16_update(newCrc, buffer[i]); 
    } 
    return newCrc; 
} 

int crc16_update(int crc, int a) 
{ 
    int i; 
    crc ^= a; 

    for (i = 0; i < 8; ++i) { 
     if ((crc & 1) == 1){ 
      crc = (crc >> 1)^0xA001; 
     } 
     else{ 
      crc = (crc >> 1); 
     } 
    } 
    return crc; 
} 

Например, когда мы помещаем два случая:

byte[] buffer = 0x2 0x14 0x14 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0

Результат является:

int result = 26997 
byte[] result = 0x69 0x75 

Может быть кто-нибудь может мне помочь найти правильный путь, я понятия не имею, что это неправильно ...

+0

Моя Java немного ржавая, но я думаю, что вам нужен логический сдвиг '>>>' для обработки значений так, как C++ обрабатывает неподписанные значения (заполняя нулем вместо знакового бита). –

+0

Там лучший код, чем этот. Посмотрите вокруг табличного метода, это в восемь раз быстрее. – EJP

+0

Результат, который вы даете для кода C, бессмыслен: 65535 и 0x1D20 не совпадают. – Durandal

ответ

1

0x6975 или десятичное 26997 является правильный результат. Результаты C++ не имеют смысла. (Шестнадцатеричные и десятичные значения не имеют одинакового значения.)

0

Это правда ... это была моя ошибка.

Снова я проверил выход, и это была точка.

Результат в C++ это не что иное, как quint16 размер (беззнаковое целочисленное значение 2 байта 0 до 65535)

я имел Printf его в неправильном месте.

Но это не одна из причин, другая была маленькой разницей между bytearray.

 Смежные вопросы

  • Нет связанных вопросов^_^