Русская Википедия:Циклический избыточный код

Материал из Онлайн справочника
Перейти к навигацииПерейти к поиску

Шаблон:О Циклический избыточный код (Шаблон:Lang-en) — алгоритм нахождения контрольной суммы, предназначенный для проверки целостности данных[1]. CRC является практическим приложением помехоустойчивого кодирования, основанным на определённых математических свойствах циклического кода.

Введение

Шаблон:Main Понятие циклические коды — достаточно широкое[2]. В англоязычной литературе CRC понимается двояко в зависимости от контекста: Cyclic Redundancy Code или Cyclic Redundancy Check[3]. Под первым понятием подразумевают математический феномен циклических кодов, под вторым — конкретное применение этого феномена как хеш-функции.

Циклические коды не только просты в реализации, но и обладают тем преимуществом, что подходят для обнаружения пакетных ошибок: непрерывных последовательностей ошибочных символов данных в сообщениях. Это важно, потому что пакетные ошибки являются распространёнными ошибками передачи во многих каналах связи, включая магнитные и оптические запоминающие устройства. Обычно n‑разрядный CRC, применяемый к блоку данных произвольной длины, и при расположении контрольной суммы непосредственно вслед за данными, обнаруживает любой одиночный пакет ошибок длиной не более n бит, а доля всех более длинных пакетов ошибок, которые он обнаружит, равна (1 − 2−n). Шаблон:Заготовка раздела

Помехоустойчивое кодирование

Шаблон:Main Первые попытки создания кодов с избыточной информацией начались задолго до появления современных компьютеров. К примеру, ещё в 1960-х годах Ридом и Соломоном была разработана эффективная методика кодирования — Код Рида-Соломона. Использование её в те времена не представлялось возможным, так как произвести операцию декодирования за разумное время первыми алгоритмами не удавалось. Точку в этом вопросе поставила фундаментальная работа Берлекэмпа, опубликованная в 1968 году. Эта методика, на практическое применение которой указал через год Мэсси, и по сей день используется в цифровых устройствах, обеспечивающих приём RS-кодированных данных. Более того: данная система позволяет не только определять позиции, но и исправлять неверные кодовые символы (чаще всего октеты).

Но далеко не всегда от кода требуется коррекция ошибок. Многие современные каналы связи обладают приемлемыми характеристиками, и зачастую достаточно лишь проверить, успешно ли прошла передача или возникли какие-нибудь сложности; структура же ошибок и конкретные позиции неверных символов совершенно не интересуют принимающую сторону. И в этих условиях очень удачным решением оказались алгоритмы, использующие контрольные суммы. CRC как нельзя лучше подходит для подобных задач: невысокие затраты ресурсов, простота реализации и уже сформированный математический аппарат из теории линейных циклических кодов обеспечили ей огромную популярность.

Хотя код CRC используют обычно только для обнаружения ошибок, его математические свойства дают возможность найти и исправить одиночную ошибку в блоке бит, если каждому биту защищаемого блока (включая проверочные биты) соответствует свой уникальный остаток от деления на порождающий многочлен. Например, если порождающий многочлен неприводим, и длина блока не превышает порядок порождённой циклической группы.

Контрольная сумма

Шаблон:Main В общем виде контрольная сумма представляет собой некоторое значение, вычисленное по определённой схеме на основе кодируемого сообщения. Проверочная информация при систематическом кодировании приписывается к передаваемым данным. На принимающей стороне абонент знает алгоритм вычисления контрольной суммы: соответственно, программа имеет возможность проверить корректность принятых данных.

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

Математическое описание

Алгоритм CRC базируется на свойствах деления с остатком двоичных многочленов, то есть многочленов над конечным полем <math> GF(2) </math>. Значение CRC является по сути остатком от деления многочлена, соответствующего входным данным, на некий фиксированный порождающий многочлен.

Каждой конечной последовательности битов <math>a_0, a_1, \dots, a_{N-1}</math> взаимно однозначно сопоставляется двоичный полином <math>\textstyle\sum_{n=0}^{N-1} a_n x^n</math>, последовательность коэффициентов которого представляет собой исходную последовательность. Например, последовательность битов 1011010 соответствует многочлену:

<math>P(x) = 1\cdot x^6 + 0\cdot x^5 + 1\cdot x^4 + 1\cdot x^3 + 0\cdot x^2 + 1\cdot x^1 + 0\cdot x^0 = x^6 + x^4 + x^3 + x^1.</math>

Количество различных многочленов степени, меньшей <math>N</math>, равно <math>2^N</math>, что совпадает с числом всех двоичных последовательностей длины <math>N</math>.

Значение контрольной суммы в алгоритме с порождающим многочленом <math>G(x)</math> степени <math>N</math> определяется как битовая последовательность длины <math>N</math>, представляющая многочлен <math>R(x)</math>, получившийся в остатке при делении многочлена <math>P(x)</math>, представляющего входной поток бит, на многочлен <math>G(x)</math>:

<math>R(x) = P(x)\cdot x^N\, \bmod\, G(x)</math>

где

<math>R(x)</math> — многочлен, представляющий значение CRC;
<math>P(x)</math> — многочлен, коэффициенты которого представляют входные данные;
<math>G(x)</math> — порождающий многочлен;
<math> N </math> — степень порождающего многочлена.

Умножение <math>x^N</math> осуществляется приписыванием <math>N</math> нулевых битов к входной последовательности, что улучшает качество хеширования для коротких входных последовательностей.

При делении с остатком различных исходных многочленов на порождающий полином <math>G(x)</math> степени <math>N</math> можно получить <math>2^{N}</math> различных остатков от деления. <math>G(x)</math> зачастую является неприводимым многочленом. Обычно его подбирают в соответствии с требованиями к хеш-функции в контексте каждого конкретного применения.

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

Вычисление CRC

Шаблон:Викиучебник

Параметры алгоритма

Одним из основных параметров CRC является порождающий полином.

С порождающим полиномом связан другой параметр — его степень, которая определяет количество битов, используемых для вычисления значения CRC. На практике наиболее распространены 8-, 16- и 32-битовые слова, что является следствием особенностей архитектуры современной вычислительной техники.

Ещё одним параметром является начальное (стартовое) значение слова. Указанные параметры полностью определяют «традиционный» алгоритм вычисления CRC. Существуют также модификации алгоритма, например, использующие обратный порядок обработки битов.

Описание процедуры

Из файла берётся первое слово — это может быть битовый (CRC-1), байтовый (CRC-8) или любой другой элемент. Если старший бит в слове «1», то слово сдвигается влево на один разряд с последующим выполнением операции XOR с порождающим полиномом. Соответственно, если старший бит в слове «0», то после сдвига операция XOR не выполняется. После сдвига теряется старший бит, а на место младшего бита загружается очередной бит из файла, и операция повторяется до тех пор, пока не загрузится последний бит файла. После прохождения всего файла в слове остаётся остаток, который и является контрольной суммой.

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

В то время как циклические избыточные коды являются частью стандартов, у этого термина не существует общепринятого определения — трактовки различных авторов нередко противоречат друг другу[4][5].

Этот парадокс касается и выбора многочлена-генератора: зачастую стандартизованные полиномы не являются самыми эффективными в плане статистических свойств соответствующего им check redundancy code.

При этом многие широко используемые полиномы не являются наиболее эффективными из всех возможных. В 1993—2004 годах группа учёных занималась исследованием порождающих многочленов разрядности до 16[4] 24 и 32 бит[6][7] и нашла полиномы, дающие лучшую, нежели стандартизированные многочлены, производительность в смысле кодового расстояния[7]. Один из результатов этого исследования уже нашёл своё применение в протоколе iSCSI.

Самый популярный и рекомендуемый IEEE полином для CRC-32 используется в Ethernet, FDDI; также этот многочлен является генератором кода Хемминга[8]. Использование другого полинома — CRC-32C — позволяет достичь такой же производительности при длине исходного сообщения от 58 бит до 131 кбит, а в некоторых диапазонах длины входного сообщения может быть даже выше, поэтому в наши дни он тоже пользуется популярностью[7]. К примеру, стандарт ITU-T G.hn использует CRC-32C с целью обнаружения ошибок в полезной нагрузке.

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

Название Полином Представления:[9] нормальное / реверсированное / реверсированное от обратного
CRC-1 <math>x + 1</math> (используется в аппаратном контроле ошибок; также известен как бит чётности) 0x1 / 0x1 / 0x1
CRC-4-ITU <math>x^4 + x + 1</math> (ITU G.704[10]) 0x3 / 0xC / 0x9
CRC-5-EPC <math>x^5 + x^3 + 1</math> (Gen 2 RFID[11]) 0x09 / 0x12 / 0x14
CRC-5-ITU <math>x^5 + x^4 + x^2 + 1</math> (ITU G.704[12]) 0x15 / 0x15 / 0x1A
CRC-5-USB <math>x^5 + x^2 + 1</math> (USB token packets) 0x05 / 0x14 / 0x12
CRC-6-ITU <math>x^6 + x + 1</math> (ITU G.704[13]) 0x03 / 0x30 / 0x21
CRC-7 <math>x^7 + x^3 + 1</math> (системы телекоммуникации, ITU-T G.707[14], ITU-T G.832[15], MMC, SD) 0x09 / 0x48 / 0x44
CRC-8-CCITT <math>x^8 + x^2 + x + 1</math> (ATM HEC), ISDN Header Error Control and Cell Delineation ITU-T I.432.1 (02/99) 0x07 / 0xE0 / 0x83
CRC-8-Dallas/Maxim <math>x^8 + x^5 + x^4 + 1</math> (1-Wire bus) 0x31 / 0x8C / 0x98
CRC-8 <math>x^8 + x^7 + x^6 + x^4 + x^2 + 1</math> (ETSI EN 302 307[16], 5.1.4) 0xD5 / 0xAB / 0xEA[4]
CRC-8-SAE J1850 <math>x^8 + x^4 + x^3 + x^2 + 1</math> 0x1D / 0xB8 / 0x8E
CRC-10 <math>x^{10} + x^9 + x^5 + x^4 + x + 1</math> 0x233 / 0x331 / 0x319
CRC-11 <math>x^{11} + x^9 + x^8 + x^7 + x^2 + 1</math> (FlexRay[17]) 0x385 / 0x50E / 0x5C2
CRC-12 <math>x^{12} + x^{11} + x^3 + x^2 + x + 1</math> (системы телекоммуникации[18][19]) 0x80F / 0xF01 / 0xC07
CRC-15-CAN <math>x^{15} + x^{14} + x^{10} + x^8 + x^7 + x^4 + x^3 + 1 </math> 0x4599 / 0x4CD1 / 0x62CC
CRC-16-IBM <math>x^{16} + x^{15} + x^2 + 1</math> (Bisync, Modbus, USB, ANSI X3.28[20], многие другие; также известен как CRC-16 и CRC-16-ANSI) 0x8005 / 0xA001 / 0xC002
CRC-16-CCITT <math>x^{16} + x^{12} + x^5 + 1</math> (X.25, HDLC, XMODEM, Bluetooth, SD и др.) 0x1021 / 0x8408 / 0x8810[4]
CRC-16-T10-DIF <math>x^{16} + x^{15} + x^{11} + x^{9} + x^8 + x^7 + x^5 + x^4 + x^2 + x + 1</math> (SCSI DIF) 0x8BB7[21] / 0xEDD1 / 0xC5DB
CRC-16-DNP <math>x^{16} + x^{13} + x^{12} + x^{11} + x^{10} + x^8 + x^6 + x^5 + x^2 + 1</math> (DNP, IEC 870, M-Bus) 0x3D65 / 0xA6BC / 0x9EB2
CRC-16-Fletcher Не CRC; см. Fletcher's checksum Используется в Adler-32 A & B CRC
CRC-24 <math>x^{24} + x^{22} + x^{20} + x^{19} + x^{18} + x^{16} + x^{14} + x^{13} + x^{11} + x^{10} + x^8 + x^7 + x^6 + x^3 + x + 1</math> (FlexRay[17]) 0x5D6DCB / 0xD3B6BA / 0xAEB6E5
CRC-24-Radix-64 <math> x^{24} + x^{23} + x^{18} + x^{17} + x^{14} + x^{11} + x^{10} + x^7 + x^6 + x^5 + x^4 + x^3 + x + 1 </math> (OpenPGP) 0x864CFB / 0xDF3261 / 0xC3267D
CRC-30 <math>x^{30} + x^{29} + x^{21} + x^{20} + x^{15} + x^{13} + x^{12} + x^{11} + x^{8} + x^{7} + x^{6} + x^{2} + x + 1 </math> (CDMA) 0x2030B9C7 / 0x38E74301 / 0x30185CE3
CRC-32-Adler Не CRC; см. Adler-32 См. Adler-32
CRC-32-IEEE 802.3 <math>x^{32} + x^{26} + x^{23} + x^{22} + x^{16} + x^{12} + x^{11} + x^{10} + x^8 + x^7 + x^5 + x^4 + x^2 + x + 1</math> (V.42, MPEG-2, PNG[22], POSIX cksum) 0x04C11DB7 / 0xEDB88320 / 0x82608EDB[7]
CRC-32C (Castagnoli) <math>x^{32} + x^{28} + x^{27} + x^{26} + x^{25} + x^{23} + x^{22} + x^{20} + x^{19} + x^{18} + x^{14} + x^{13} + x^{11} + x^{10} + x^9 + x^8 + x^6 + 1</math> (iSCSI, G.hn payload) 0x1EDC6F41 / 0x82F63B78 / 0x8F6E37A0[7]
CRC-32K (Koopman) <math>x^{32} + x^{30} + x^{29} + x^{28} + x^{26} + x^{20} + x^{19} + x^{17} + x^{16} + x^{15} + x^{11} + x^{10} + x^{7} + x^{6} + x^{4} + x^{2} + x + 1</math> 0x741B8CD7 / 0xEB31D82E / 0xBA0DC66B[7]
CRC-32Q <math>x^{32} + x^{31} + x^{24} + x^{22} + x^{16} + x^{14} + x^{8} + x^{7} + x^{5} + x^{3} + x + 1</math> (aviation; AIXM[23]) 0x814141AB / 0xD5828281 / 0xC0A0A0D5
CRC-64-ISO <math>x^{64} + x^4 + x^3 + x + 1</math> (HDLC — ISO 3309) 0x000000000000001B / 0xD800000000000000 / 0x800000000000000D
CRC-64-ECMA <math>x^{64} + x^{62} + x^{57} + x^{55} + x^{54} + x^{53} + x^{52} + x^{47} + x^{46} + x^{45} + x^{40} + x^{39} + x^{38} + x^{37} + x^{35} + x^{33} +</math> <math>x^{32} + x^{31} + x^{29} + x^{27} + x^{24} + x^{23} + x^{22} + x^{21} + x^{19} + x^{17} + x^{13} + x^{12} + x^{10} + x^9 + x^7 + x^4 + x + 1</math>[24] 0x42F0E1EBA9EA3693 / 0xC96C5795D7870F42 / 0xA17870F5D4F51B49

Существующие стандарты CRC-128 (IEEE) и CRC-256 (IEEE) в настоящее времяШаблон:Когда вытеснены криптографическими хеш-функциями.

Спецификации алгоритмов CRC

Одной из самых известных является методика Ross N. Williams[25]. В ней используются следующие параметры:

  • Название алгоритма (name);
  • Степень порождающего контрольную сумму многочлена (width);
  • Сам производящий полином (poly). Для того, чтобы записать его в виде значения, его сначала записывают как битовую последовательность, при этом старший бит опускается — он всегда равен 1. К примеру, многочлен <math> x^8+x^4+1 </math> в данной нотации будет записан числом <math> 00010001_2 </math>. Для удобства полученное двоичное представление записывают в шестнадцатеричной форме. Для нашего случая оно будет равно <math>11_h</math> или 0x11;
  • Стартовые данные (init), то есть значения регистров на момент начала вычислений;
  • Флаг (RefIn), указывающий на начало и направление вычислений, для обнаружения пакетов ошибок должно соответствовать порядку передачи в канале. Существует два варианта: False — начиная со старшего значащего бита (MSB-first) или True — с младшего (LSB-first);
  • Флаг (RefOut), определяющий, инвертируется ли порядок битов регистра при входе на элемент XOR;
  • Число (XorOut), с которым складывается по модулю 2 полученный результат;
  • Значение CRC (check) для строки «123456789» .
Примеры[26]
Name Width Poly Init RefIn RefOut XorOut Check
CRC-3/ROHC 3 0x3 0x7 true true 0x0 0x6
CRC-4/ITU 4 0x3 0x0 true true 0x0 0x7
CRC-5/EPC 5 0x9 0x9 false false 0x0 0x0
CRC-5/ITU 5 0x15 0x0 true true 0x0 0x7
CRC-5/USB 5 0x5 0x1F true true 0x1F 0x19
CRC-6/CDMA2000-A 6 0x27 0x3F false false 0x0 0xD
CRC-6/CDMA2000-B 6 0x7 0x3F false false 0x0 0x3B
CRC-6/DARC 6 0x19 0x0 true true 0x0 0x26
CRC-6/ITU 6 0x3 0x0 true true 0x0 0x6
CRC-7 7 0x9 0x0 false false 0x0 0x75
CRC-7/ROHC 7 0x4F 0x7F true true 0x0 0x53
CRC-8 8 0x7 0x0 false false 0x0 0xF4
CRC-8/CDMA2000 8 0x9B 0xFF false false 0x0 0xDA
CRC-8/DARC 8 0x39 0x0 true true 0x0 0x15
CRC-8/DVB-S2 8 0xD5 0x0 false false 0x0 0xBC
CRC-8/EBU 8 0x1D 0xFF true true 0x0 0x97
CRC-8/I-CODE 8 0x1D 0xFD false false 0x0 0x7E
CRC-8/ITU 8 0x7 0x0 false false 0x55 0xA1
CRC-8/MAXIM 8 0x31 0x0 true true 0x0 0xA1
CRC-8/ROHC 8 0x7 0xFF true true 0x0 0xD0
CRC-8/WCDMA 8 0x9B 0x0 true true 0x0 0x25
CRC-10 10 0x233 0x0 false false 0x0 0x199
CRC-10/CDMA2000 10 0x3D9 0x3FF false false 0x0 0x233
CRC-11 11 0x385 0x1A false false 0x0 0x5A3
CRC-12/3GPP 12 0x80F 0x0 false true 0x0 0xDAF
CRC-12/CDMA2000 12 0xF13 0xFFF false false 0x0 0xD4D
CRC-12/DECT 12 0x80F 0x0 false false 0x0 0xF5B
CRC-13/BBC 13 0x1CF5 0x0 false false 0x0 0x4FA
CRC-14/DARC 14 0x805 0x0 true true 0x0 0x82D
CRC-15 15 0x4599 0x0 false false 0x0 0x59E
CRC-15/MPT1327 15 0x6815 0x0 false false 0x1 0x2566
CRC-16/ARC 16 0x8005 0x0 true true 0x0 0xBB3D
CRC-16/AUG-CCITT 16 0x1021 0x1D0F false false 0x0 0xE5CC
CRC-16/BUYPASS 16 0x8005 0x0 false false 0x0 0xFEE8
CRC-16/CCITT-FALSE 16 0x1021 0xFFFF false false 0x0 0x29B1
CRC-16/CDMA2000 16 0xC867 0xFFFF false false 0x0 0x4C06
CRC-16/DDS-110 16 0x8005 0x800D false false 0x0 0x9ECF
CRC-16/DECT-R 16 0x0589 0x0 false false 0x1 0x7E
CRC-16/DECT-X 16 0x0589 0x0 false false 0x0 0x7F
CRC-16/DNP 16 0x3D65 0x0 true true 0xFFFF 0xEA82
CRC-16/EN-13757 16 0x3D65 0x0 false false 0xFFFF 0xC2B7
CRC-16/GENIBUS 16 0x1021 0xFFFF false false 0xFFFF 0xD64E
CRC-16/MAXIM 16 0x8005 0x0 true true 0xFFFF 0x44C2
CRC-16/MCRF4XX 16 0x1021 0xFFFF true true 0x0 0x6F91
CRC-16/RIELLO 16 0x1021 0xB2AA true true 0x0 0x63D0
CRC-16/T10-DIF 16 0x8BB7 0x0 false false 0x0 0xD0DB
CRC-16/TELEDISK 16 0xA097 0x0 false false 0x0 0xFB3
CRC-16/TMS37157 16 0x1021 0x89EC true true 0x0 0x26B1
CRC-16/USB 16 0x8005 0xFFFF true true 0xFFFF 0xB4C8
CRC-A 16 0x1021 0xC6C6 true true 0x0 0xBF05
CRC-16/KERMIT 16 0x1021 0x0 true true 0x0 0x2189
CRC-16/MODBUS 16 0x8005 0xFFFF true true 0x0 0x4B37
CRC-16/X-25 16 0x1021 0xFFFF true true 0xFFFF 0x906E
CRC-16/XMODEM 16 0x1021 0x0 false false 0x0 0x31C3
CRC-24 24 0x864CFB 0xB704CE false false 0x0 0x21CF02
CRC-24/FLEXRAY-A 24 0x5D6DCB 0xFEDCBA false false 0x0 0x7979BD
CRC-24/FLEXRAY-B 24 0x5D6DCB 0xABCDEF false false 0x0 0x1F23B8
CRC-31/PHILIPS 31 0x04C11DB7 0x7FFFFFFF false false 0x7FFFFFFF 0xCE9E46C
CRC-32/zlib 32 0x04C11DB7 0xFFFFFFFF true true 0xFFFFFFFF 0xCBF43926
CRC-32/BZIP2 32 0x04C11DB7 0xFFFFFFFF false false 0xFFFFFFFF 0xFC891918
CRC-32C 32 0x1EDC6F41 0xFFFFFFFF true true 0xFFFFFFFF 0xE3069283
CRC-32D 32 0xA833982B 0xFFFFFFFF true true 0xFFFFFFFF 0x87315576
CRC-32/MPEG-2 32 0x04C11DB7 0xFFFFFFFF false false 0x0 0x376E6E7
CRC-32/POSIX 32 0x04C11DB7 0x0 false false 0xFFFFFFFF 0x765E7680
CRC-32Q 32 0x814141AB 0x0 false false 0x0 0x3010BF7F
CRC-32/JAMCRC 32 0x04C11DB7 0xFFFFFFFF true true 0x0 0x340BC6D9
CRC-32/XFER 32 0xAF 0x0 false false 0x0 0xBD0BE338
CRC-40/GSM 40 0x4820009 0x0 false false 0xFFFFFFFFFF 0xD4164FC646
CRC-64 64 0x42F0E1EBA9EA3693 0x0 false false 0x0 0x6C40DF5F0B497347
CRC-64/WE 64 0x42F0E1EBA9EA3693 0xFFFFFFFFFFFFFFFF false false 0xFFFFFFFFFFFFFFFF 0x62EC59E3F1A4F00A
CRC-64/XZ 64 0x42F0E1EBA9EA3693 0xFFFFFFFFFFFFFFFF true true 0xFFFFFFFFFFFFFFFF 0x995DC9BBDF1939FA

Примечания

Шаблон:Примечания

Литература

Ссылки

Шаблон:Викиучебник

CRC Калькуляторы


Шаблон:Хеш-алгоритмы