CRC-арифметика Програмування, уроки та приклади

Розрахунки CRC ведуться у двійковій системі числення. При проведенні CRC-вирахувань використовується спеціальна CRC-арифметика, яка, по суті, є поліноміальною арифметикою за модулем 2. Поліноміальна арифметика за модулем 2 — це ще один із видів арифметик, що використовуються для вирішення завдань у певній предметній галузі та відрізняються від звичної двійкової арифметики з циклічним переносом відсутністю переносів та обчисленням всіх коефіцієнтів за модулем 2 . У уроці 20 «ММХ-технологія мікропроцесорів Intel» підручника під час розгляду ММХ-команд ми знайомилися з однією з таких альтернативних арифметик — арифметикою з насиченням. Тепер розглянемо особливості CRC-арифметики. Отже, як зазначено вище, в основі CRC-арифметики лежить поліноміальна арифметика. За визначенням, поліном - лінійна комбінація (сума) творів цілих ступенів заданого набору змінних із постійними коефіцієнтами. Окремий випадок - поліном, що містить одну змінну:

Тут un, nu щ - елементи деякої системи алгебри S, звані коефіцієнтами; х - змінна полінома, яку можна розглядати як формальний символ без певного значення. Алгебраїчна система S зазвичай являє собою безліч цілих або раціональних чисел в діапазоні 0..m-1 із додаванням, відніманням і множенням, що виконуються за модулем т. Для нашого розгляду особливо важлива поліноміальна арифметика за модулем 2, в якій кожен коефіцієнт полінома дорівнює одному з двох значень - 0 або 1. Наприклад, шістнадцяткове значення ОЕЗп може бути представлене наступним поліномом:

1х2 7 + 1х2 6 + 1х2 5 + 0х2 4 + 0х2 3 + 0х2 2 + 1x2 1 + 1x2 °.

Якщо ввести як змінну х=2, то отримаємо наступний двійковий поліном:

1хx 7 + 1xx 6 + 1xx 5 + 0хх 4 + 0xx 3 + 0xx 2 +1xx 1 + 1хх °.

У цьому поліномі, строго кажучи, значення х не відіграє особливої ​​ролі, так як дане двійкове число можна уявити поліномом в іншій системі числення, наприклад, шістнадцятковій: ехх 1 + 2хх °, де х = 16. При цьому зауважимо, що в тому і В іншому випадку цифри 0, 1, е, 2 — це просто цифри двійкової та шістнадцяткової систем числення. Оскільки складові двійкового полінома з нульовими коефіцієнтами не дають жодного вкладу в кінцевий результат, то їх можна просто відкинути, залишивши тільки доданки, змінні яких мають одиничні коефіцієнти:

1xx7 + 1xx6 + 1xx5 + 0xx4 + 0xx3 + 0xx2 + 1xx1 + 1хх ° - = 1xx7 +1xx6 + lxx5 + 1xx1 + 1xx0 = = x7 + x6 + x5 + x1 + x°.

Тут x = 2. Над поліномами можна виконувати арифметичні операції: додавання, множення та віднімання. Процеси виконання цих операцій для поліноміальної арифметики та звичайної арифметики багаторазової точності (див. Розділ 1) схожі. Головна відмінність у тому, що через відсутність зв'язку між коефіцієнтами полінома поняття перенесення у поліноміальній арифметиці відсутнє. Наприклад, для множення 7h (0111b) на 5h (0101b) виконуються дії:

(х2 + х1 + х °) х (х2 + х °) = (х4 + х3 + х2 + х2 + х1 + х °) - = х4 + х3 + х2 + х2 + х1 + х ° + х ° = х4 + х3 + 2х2 + х1 + 2х °.

Для того щоб отримати у відповіді 35, ми повинні взяти х рівним 2 і привести коефіцієнти у членів полінома 2х° і 2х2 до двійкових, зробивши перенесення відповідних одиниць у старші розряди: 01010 переноси 11111 результат 100011 = 35)0. У результаті отримаємо двійковий поліном х5+х'+х°. Ці міркування покликані сформулювати чергову тезу про те, що переноси, як і в звичайній арифметиці, можна виконувати у випадку, коли відома основа системи числення. Тобто доти, доки ми не знаємо х, ми неможемо виробляти та переноси. У наведеному вище прикладі ми не знаємо, що 2х2 і 2х° насправді є х3 і х1 до тих пір, поки не відомо, що х = 2. Тобто в поліноміальній арифметиці коефіцієнти при різних ступенях ізольовані один від одного і відносини між ними не визначено. Через це виникає перша дивина поліноміальної арифметики — операції додавання та віднімання в ній абсолютно ідентичні і замість них можна сміливо залишати одну. Наприклад, додавання за правилами поліноміальної арифметики за модулем 2, її далі називатимемо CRC-арифметикою, буде виконано так:

З цього прикладу видно правила складання двійкових розрядів в арифметиці t з відсутністю переносів:

0+0=0; 0+1 = 1; 1+0=1; 1+1=0.

Операцію віднімання демонструє наступний приклад:

Правила виконання віднімання в арифметиці з відсутністю переносів:

Порівняння прикладів для складання та віднімання поліномів за модулем 2, а також правил, за якими вони виконуються, показує те, що ці дві операції CRC-арифметики ідентичні і за принципом формування результату вони аналогічні команді асемблера XOR. Мета, якою досягають усіма цими умовностями, - виключити з поля уваги всі величини (шляхом позик/переносів), що лежать за кордоном старшого розряду. Умноження в арифметиці з відсутністю переносів також виконується з урахуванням особливостей CRC-складання:

Видно, що в множенні особливостей немає, а ось додавання проміжних результатів проводиться за правилами CRC-складання. Для нашого розгляду особливий інтерес представляє операція поділу, так як в основі будь-якого алгоритму обчислення CRC лежить подання вихідного повідомлення у вигляді величезного двійкового числа, поділ його на інше двійкове число і використання залишку від цього поділу вяк значення CRC. Поділ - найскладніша з операцій CRC-арифметики. Тут необхідно ввести так зване слабке поняття розмірності: число X більше або дорівнює числу Y, якщо обидва числа мають однакову розмірність і позиції старших бітів одиничні, тобто співвідношення інших бітів X і Y для операції порівняння не має значення. Розглянемо приклади операції поділу, причому для кращого розуміння зробимо це у двох варіантах: спочатку пригадаємо, як виконується звичайний поділ (за правилами двійкової арифметики з циклічним переносом), а потім виконаємо власне CRC-поділ. Візьмемо довільну двійкову послідовність і розділимо її на деяке число за правилами двійкової арифметики з циклічним перенесенням (рис. 9.3). За правилами CRC-арифметики розподіл для наведених вище вихідних даних дасть наступний результат (рис. 9.4).

уроки

Мал. 9.3. Схема обчислення двійкового поділу (з циклічним перенесенням)

уроки

Мал. 9.4. Схема обчислення CRC-розподілу

Як бачите, результати звичайного та CRC-поділів відрізняються. Головне, щоб ви помітили особливість виконання CRC поділу. Особливу увагу зверніть на порядок формування проміжних результатів у процесі розподілу. Знесення двійкових розрядів з ділимого триває до того часу, поки розмірності проміжного бітового значення і дільника не зрівняються, які старші розряди стануть рівними 1. Після цього над двійковими розрядами виконується побитовое CRC-віднімання. Співвідношення розрядів не має значення, головне — це однакова розмірність і одиничні старші біти. У цьому випадку вважається, що віднімається більше віднімається, що тягне за собою включення 1 у приватне та виконання операції CRC-віднімання. Це і є прояв слабкого поняття розмірності. Кошик для сміття,показана на рис. 9.4 означає той факт, що приватне для процесу обчислення CRC-бітової послідовності не має ніякого значення. Реальні двійкові послідовності є результатом зчеплення часом величезної кількості окремих байтів (символів), утворюючи одне велике двійкове число, для представлення якого потрібно використовувати двійкові поліноми величезних ступенів. При цьому кожен біт у подібній послідовності довільної довжини представляється як коефіцієнт довгого полінома. Наприклад, для представлення 128-розрядного блоку необхідний поліном, що складається з 1024 доданків, а для 1024-бітного блоку необхідний поліном вже з 8192 доданками. У термінах поліноміальної арифметики двійкове число, сформоване в результаті подібного зчеплення складових блоку даних, називається поліномом даних

  • породжує поліпом G(x) — попередньо особливим чином обраний поліном, який ділиться вихідний поліном повідомлення;
  • поліном-приватне Q(x) - поліном, що вийшов як приватний від поділу поліномів D(x)/G(x);
  • поліном-залишок R(x) - поліном, що вийшов як залишок від поділу поліномів D(x)/G(x).

Між переліченими поліномами існують такі відносини: D(x)=Q(x)xG(x)+R(x), Q(x)=(D(x)-R(x))/G(x) . Ці співвідношення призводять до наступних основоположних для подальшого розгляду тез:

  • операція поділу двох двійкових поліномів D(x)/G(x), де G(x)*0, дає як результат поліном-приватне Q(x) і поліном-залишок R(x), що задовольняють умовам: D(x) =Q(x)xG(x)+R(x);
  • залишок від поділу двох поліномів R(x) є двійковим числом, яке після віднімання з D(x) дає в результаті ще один поліном, що ділиться без залишку на G(x); що виходить в результаті цьогоділення приватне Q(x) відкидається через непотрібність, а поліном-залишок R(x) називають CRC (Cyclic Redundancy Code).

З наведеного вище описи загальної схеми обчислення CRC виникає низка питань: що є цей магічний дільник G(x), який його розмір? Вибір полінома G(x), що породжує, — досить складне завдання. Перерахуємо деякі важливі властивості, які повинні враховуватись при цьому.

  • Число розрядів (кількість членів) у поліномі-залишку R(x) безпосередньо визначається довжиною самого породжуючого полінома G(x). Вибір G(x) довжиною п гарантує, що полином-залишок від розподілу R(x) матиме розрядність трохи більше, ніж п-1. Це випливає із загальної властивості операції поділу, яка передбачає, що залишок від поділу повинен бути меншим від дільника.
  • Що породжує поліном G(x) має бути поліноміально простим. Це означає його неподільність націло на поліноми зі значенням у діапазоні від 2 до самого себе.
  • Здатність породжує полінома G(x) до виявлення помилок, специфічних передачі даних каналами зв'язку. Це такі помилки, як помилки в одному, двох, непарному кількості бітів, а також помилки блоку бітів. Вище ми зазначали, що простіші методи виявлення помилок передачі не здатні виявити з достатньою мірою ймовірності більшість таких типів помилок.

Для більшості алгоритмів обчислення CRC значення полінома, що породжує, відомо заздалегідь і, більше того, затверджено відповідними стандартами. Тому програмісту без особливої ​​потреби не варто втрачати часу і сил на винахід нового значення полінома, що породжує G(x). Наведемо значення деяких широко відомих поліномів, які використовуються практично.

  • х'6 + х12 + х5 + х ° - поліном 1021h, що використовується в протоколі XMODEMта похідних від нього протоколах передачі даних. Він стандартизований у специфікації V.41 МККТТ «Кодонезалежна система контролю помилок». Ш х16 + х5 + х2 + х ° - поліном 8005h, що використовується в протоколі двійкової синхронної передачі фірми IBM. Він також стандартизований у додатку А «Процедура корекції помилок кінцевого обладнання лінії з використанням асинхронно-синхронного перетворення» до стандарту V.42 МККТТ. Цей поліном широко відомий як поліном, що використовується в алгоритмі обчислення CRC - CRC16.
  • x32+x26+x23+x22+x16+x12+x"+xlo+xs+x7+x5+x4+x2+x1+x0 - поліном 04clldb7h, який використовується в алгоритмі обчислення CRC - CRC32 і також стандартизований у стандарті V.42 МККТТ Цей поліном, зокрема, використовується в технології локальних обчислювальних мереж Ethernet, необхідно зазначити, що обчислення за алгоритмом CRC32 часто проводять і з іншим поліномом: 0edb88320h:
  • x32+x31+x30+x29+x27+x26+x24+x23+x21+x20+ х19+х15+х9+х8+х5. Останній поліном використовують різноманітні архіватори. Поліном 0edb88320h - це дзеркальне відображення полінома 04clldb7h.

Насамкінець зазначимо, чому вигідно збільшувати число розрядів CRC. Вище вже було зазначено, що алгоритм обчислення CRC за своєю суттю є одним із можливих (і непоганих) алгоритмів хешування. Розрядність полінома G(x) 16 біт, що породжує, забезпечує до 65 535 значень хеш-функції. Збільшення розрядності полінома G(x) до 32 бітів призводить до розширення набору значень хеш-функції вже до 4 294 967 295. з нуля). Наприклад, для полінома 1011 з наведеного вище прикладу (див. рис. 9.4) ступінь дорівнює 3.висновків відзначимо, що CRC-арифметика відрізняється від двійковою відсутністю переносів/позик, а CRC-віднімання та додавання виконуються за тими самими правилами, що і команда асемблера XOR, що і обумовлює її важливу роль при обчисленні значень CRC.