GolfScript, 60 символів
{[[0 1{.283{1$2*.255>@*^}:r~^}255*].@?~)={257r}4*99]{^}*}:S;
Цей код визначає функцію з назвою, Sяка бере байт і застосовує до неї S-поле Rijndael. (Також використовується внутрішня допоміжна функція, імені rдля збереження кількох символів.)
Ця реалізація використовує таблицю логарифмів для обчислення обертів GF (2 8 ), як це запропонував Томас Порнін . Щоб зберегти кілька символів, вся таблиця логарифмів перераховується на кожен вхідний байт; тим не менше, і незважаючи на те, що GolfScript взагалі дуже повільна мова, цей код займає лише близько 10 мс для обробки байта на моєму старому ноутбуці. Попередній розрахунок таблиці логарифмів (як L) прискорює його до приблизно 0,5 мс на байт, за скромної вартості ще трьох символів:
[0 1{.283{1$2*.255>@*^}:r~^}255*]:L;{[L?~)L={257r}4*99]{^}*}:S;
Для зручності ось простий тестовий джгут, який викликає функцію S, визначену вище, для обчислення та виведення всього S-вікна в шістнадцятковій формі, як у Вікіпедії :
"0123456789abcdef"1/:h; 256, {S .16/h= \16%h= " "++ }% 16/ n*
Спробуйте цей код в Інтернеті.
(Демонстрація в Інтернеті заздалегідь обчислює таблицю логарифмів, щоб уникнути занадто багато часу. Навіть так, веб-сайт GolfScript іноді може випадково вичерпатися; це відома проблема із сайтом, і перезавантаження зазвичай виправляє його.)
Пояснення:
Почнемо з розрахунку таблиці логарифмів, а конкретно з хелперної функції r:
{1$2*.255>@*^}:r
Ця функція займає два входи в стек: байт і скорочувальна бітова маска (константа між 256 і 511). Він дублює вхідний байт, помножує копію на 2 і, якщо результат перевищує 255, XOR розміщує її за допомогою бітової маски, щоб повернути її назад під 256.
У коді генеруючого коду журнальної таблиці функція rвикликається бітовою маскою скорочення 283 = 0x11b (що відповідає поліному скорочення GF Rijndael GF (2 8 ) x 8 + x 4 + x 3 + x + 1), а результат XORed з початковим байтом, ефективно помноживши його на 3 (= x + 1, як многочлен) у кінцевому полі Ріндгаеля. Це множення повторюється 255 разів, починаючи з байта 1, і результати (плюс початковий нульовий байт) збираються в масив 257 елементів, Lякий виглядає приблизно так (середня частина опущена):
[0 1 3 5 15 17 51 85 255 26 46 ... 180 199 82 246 1]
Причина, чому існує 257 елементів, полягає в тому, що, маючи попередньо встановлений 0 і 1, що виникає двічі, ми можемо знайти модульну інверсію будь-якого заданого байта, просто переглянувши його (нульовий) індекс у цьому масиві, відкинувши його та переглянувши вгору байт на індекс заперечення в тому ж масиві. (У GolfScript, як і у багатьох інших мовах програмування, індекси негативного масиву відлічуються назад від кінця масиву.) Дійсно, саме це робить код L?~)L=на початку функції S.
Решта коду викликає функцію помічника rчотири рази за допомогою зменшення бітової маски 257 = 2 8 + 1 для створення чотирьох бітових повернених копій інвертованого вхідного байта. Всі вони збираються в масив разом з постійною 99 = 0x63 і XORed разом, щоб отримати кінцевий результат.