Расчет Ethernet CRC32 - программное обеспечение против алгоритмического результата

Я пытаюсь вычислить последовательность проверки кадров (FCS) байта пакета Ethernet по байту. Полином равен 0x104C11DB7. Я выполнил описанный здесь алгоритм XOR-SHIFT http://en.wikipedia.org/wiki/Cyclic_redundancy_check или здесь http://www.woodmann.com/fravia/crctut1.htm

Предположим, что информация, которая предполагается, имеет CRC, представляет собой только один байт. Пусть говорят, что это 0x03.

  • Шаг: панель с 32 битами вправо

    0x0300000000

  • выровняйте многочлен и данные с левой стороны со своим первым битом, который не равен нулю и xor их

    0x300000000 xor 0x209823B6E = 0x109823b6e

  • взять выравнивание остатка и снова xor

    0x109823b6e xor 0x104C11DB7 = 0x0d4326d9

Так как больше нет бит, CRC32 0x03 должен быть 0x0d4326d9

К сожалению, все версии программного обеспечения говорят мне, что я ошибаюсь, но что я сделал неправильно или что они делают по-другому?

Python говорит мне:

 "0x%08x" % binascii.crc32(chr(0x03))
 0x4b0bbe37

Онлайн-инструмент здесь http://www.lammertbies.nl/comm/info/crc-calculation.html#intr получает тот же результат. В чем разница между расчетом руки и алгоритмом, используемым указанным программным обеспечением?

UPDATE:

Оказывается, был и аналогичный вопрос при переполнении стека:

Здесь вы найдете ответ Проблемы с Python CRC-32

Хотя это не очень интуитивно понятно. Если вы хотите более формальное описание того, как это делается для Ethernet-фреймов, вы можете посмотреть Стандарт Ethernet 802.3. Часть 3 - Глава 3.2. 9 Поле последовательности проверки кадров

Давайте продолжим пример сверху:

  • Отмените порядок бит вашего сообщения. Это означает, что они понемногу поступают в приемник.

    0x03, следовательно, 0xC0

  • Дополните первые 32 бит вашего сообщения. Обратите внимание, что мы добавим один байт с 32 бит снова.

    0xC000000000 xor 0xFFFFFFFF = 0x3FFFFFFF00

  • Завершите метод Xor и shift сверху. Примерно через 6 шагов вы получите:

    0x13822f2d

  • Затем добавляется вышеупомянутая последовательность бит.

    0x13822f2d xor 0xFFFFFFFF = 0xec7dd0d2

  • Помните, что мы изменили порядок бит, чтобы получить представление на Ethernet-кабеле на первом шаге. Теперь мы должны отменить этот шаг, и мы, наконец, выполним наши поиски.

    0x4b0bbe37

Тот, кто придумал этот способ сделать это, должен быть...

Много раз вы действительно хотите знать, что полученное вами сообщение является правильным. Чтобы достичь этого, вы принимаете ваше полученное сообщение, включая FCS, и делаете тот же шаг с 1 по 5, как указано выше. Результатом должно быть то, что они называют остатком. Которая является константой для данного многочлена. В этом случае это 0xC704DD7B.

Как говорится в mcdowella, вы должны играть со своими битами, пока не получите правильное решение, в зависимости от используемого вами приложения.

Ответ 1

Этот фрагмент Python записывает правильный CRC для Ethernet:

# write payload
for byte in data:
    f.write('%02X\n' % ord(byte))
# write FCS
crc = zlib.crc32(data)&0xFFFFFFFF
for i in range(4):
    b = (crc >> (8*i)) & 0xFF
    f.write('%02X\n' % b)

Если бы я нашел это здесь, я бы немного спал.

Ответ 2

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

Один из способов обойти это - посмотреть на источник программы, который будет прав, например http://sourceforge.net/projects/crcmod/files/ (по крайней мере, он утверждает для соответствия, и поставляется с unit test для этого).

Другим является воспроизведение с реализацией. Например, если я использую калькулятор в http://www.lammertbies.nl/comm/info/crc-calculation.html#intr, я вижу, что при его предоставлении 00000000 генерирует CRC 0x2144DF1C, но при этом FFFFFFFF производит FFFFFFFF - так что это не то, о чем вы описываете, о том, какое 0 будет иметь контрольную сумму 0

С быстрым взглядом на исходный код и эти результаты, я думаю, вам нужно начать с CRC 0xFFFFFFFF, но я могу ошибаться, и вы можете закончить отладку своего кода рядом с реализацией, используя соответствующие printfs для узнать, где первый отличается, и фиксируя различия один за другим.

Ответ 3

http://en.wikipedia.org/wiki/Cyclic_redundancy_check

имеет все данные для ethernet и множество важных деталей, например, есть (по крайней мере) 2 соглашения для кодирования полинома в 32-битное значение, наибольший термин сначала или наименьший член.

Ответ 4

В Интернете есть несколько мест, где вы будете читать, что порядок бит должен быть отменен перед вычислением FCS, но спецификация 802.3 не является одним из них. Цитата из версии спецификации 2008 года:

3.2.9 Frame Check Sequence (FCS) field

A cyclic redundancy check (CRC) is used by the transmit and receive algorithms to
generate a CRC value for the FCS field. The FCS field contains a 4-octet (32-bit)
CRC value. This value is computed as a function of the contents of the protected
fields of the MAC frame: the Destination Address, Source Address, Length/ Type 
field, MAC Client Data, and Pad (that is, all fields except FCS). The encoding is
defined by the following generating polynomial.

  G(x) = x32 + x26 + x23 + x22 + x16 + x12 + x11 
             + x10 + x8 + x7 + x5 + x4 + x2 + x + 1

Mathematically, the CRC value corresponding to a given MAC frame is defined by 
the following procedure:

a) The first 32 bits of the frame are complemented.
b) The n bits of the protected fields are then considered to be the coefficients
   of a polynomial M(x) of degree n – 1. (The first bit of the Destination Address
   field corresponds to the x(n–1) term and the last bit of the MAC Client Data 
   field (or Pad field if present) corresponds to the x0 term.)
c) M(x) is multiplied by x32 and divided by G(x), producing a remainder R(x) of
   degree ≤ 31.
d) The coefficients of R(x) are considered to be a 32-bit sequence.
e) The bit sequence is complemented and the result is the CRC.

The 32 bits of the CRC value are placed in the FCS field so that the x31 term is
the left-most bit of the first octet, and the x0 term is the right most bit of the
last octet. (The bits of the CRC are thus transmitted in the order x31, x30,..., 
x1, x0.) See Hammond, et al. [B37].

Конечно, остальные биты в кадре передаются в обратном порядке, но это не включает FCS. Опять же, из спецификации:

3.3 Order of bit transmission

Each octet of the MAC frame, with the exception of the FCS, is transmitted least
significant bit first.