2016-06-27 2 views
1

Я отправляю несколько сообщений с MCU на свой компьютер, и я хочу использовать 32-разрядную циклическую проверку избыточности, чтобы убедиться, что сообщения верны. Из того, что я прочитал, должно быть возможно добавить остаток CRC в последнее сообщение и запустить его через функцию CRC. Если сообщение было безошибочным, оно должно было возвращать ноль (я прав?) Я, однако, не смог реализовать это, используя библиотечную функцию binascii binascii.crc32().Проверка контрольной суммы с помощью binascii.crc32()

Предположим, например, что я хочу проверить сообщение внутри примера, приведенного в документах Python (я использую Python 3.5). Как я буду проверять, является ли сообщение ошибкой (что, конечно, в этом примере)?

crc = binascii.crc32(b"hello") 
crc = binascii.crc32(b" world", crc) 

check_for_error() # <--- ? 

ответ

1

Простой способ сделать это - просто добавить CRC в форме байта к сообщению. Затем, когда вы получаете сообщение, вы вычисляете CRC всех, кроме последних 4 байтов сообщения, и сравниваете его с добавленными байтами CRC. Конечно, это немного сложнее, чем то, что вы хотите сделать, но вы можете применить эту стратегию к криптографическим хэшам, таким как MD5 или SHA.

Однако, чтобы сделать то, что вы просите, вам нужно инвертировать CRC32, вычитая его из 0xffffffff перед преобразованием его в байты &, добавляя его. CRC32 на самом деле является обратным CRC, который предотвращает получение нуля всех нулевых байтов от нуля CRC. При декодировании сообщение может быть действительным, если CRC данных + CRC равно 0xffffffff.

Питон CRC32 документы рекомендуется использовать

crc32(data) & 0xffffffff 

вместо

crc32(data) 

, чтобы гарантировать, что вы получите тот же числовое значение во всех версиях Python и платформ.

Вот краткое описание Python 3.

import binascii 

maxcrc = 0xffffffff 

def inverse_crc(data): 
    crc = binascii.crc32(data) & maxcrc 
    invcrc = maxcrc - crc 
    return invcrc.to_bytes(4, 'little') 

def check_crc(data): 
    return binascii.crc32(data) & maxcrc == maxcrc  

#Test 

data = b"Hello, world" 
newdata = data + inverse_crc(data) 
print(check_crc(newdata)) 
newdata = b'0x00' + newdata 
print(check_crc(newdata)) 

выход

True 
False 

Обратите внимание, что вы можете получить ложные срабатывания: коррумпированное сообщение может иметь правильный CRC. Если вам нужен более высокий уровень защиты, вы должны использовать криптографический хеш. Это все еще не идеально, но вероятность ложного положительного с такими крупными хэшами чрезвычайно низкая. Разумеется, вычисление хеша MD5 или SHA равно намного медленнее, чем вычисление CRC32.

+0

Спасибо! Я попробую это позже сегодня надеемся :) – ViggoTW