Преобразование между кодеками

В основе всей криптографии в SJCL лежит тип данных bitArray. Это не строки и не байты в привычном виде, а массивы 32-битных слов с дополнительным служебным представлением длины. Именно через него проходят все операции шифрования, хэширования и кодирования.

Ключевой принцип работы библиотеки: внутри — bitArray, снаружи — кодеки (codec)

Кодеки отвечают за преобразование между bitArray и внешними форматами данных:

  • строками (UTF-8)
  • шестнадцатеричными представлениями (HEX)
  • Base64 / Base64URL
  • сырыми байтами (байтовые строки)

Представление данных в SJCL

bitArray устроен следующим образом:

  • каждый элемент массива — 32-битное число
  • старшие биты последнего слова содержат информацию о длине

Пример:

var arr = sjcl.codec.utf8String.toBits("test");

Внутри это уже не строка "test", а структура вида:

[1952805748, 1819043144, 6647396, 64]

Последний элемент 64 — длина в битах.


Основной объект codec

Все кодеки находятся в пространстве:

sjcl.codec

Основные реализации:

  • sjcl.codec.hex
  • sjcl.codec.base64
  • sjcl.codec.base64url
  • sjcl.codec.utf8String

Каждый кодек реализует два обязательных метода:

  • toBits(input)
  • fromBits(bitArray)

HEX-кодек

Преобразование строки в HEX

var bits = sjcl.codec.utf8String.toBits("hello");
var hex = sjcl.codec.hex.fromBits(bits);

Результат:

68656c6c6f

Обратное преобразование

var bits = sjcl.codec.hex.toBits("68656c6c6f");
var text = sjcl.codec.utf8String.fromBits(bits);

UTF-8 кодек

UTF-8 кодек работает с человеческими строками и выполняет преобразование в bitArray.

Строка → bitArray

var bits = sjcl.codec.utf8String.toBits("Привет");

Особенность: символы кириллицы кодируются в несколько байт, поэтому размер bitArray увеличивается непропорционально длине строки.

bitArray → строка

var str = sjcl.codec.utf8String.fromBits(bits);

Base64 кодек

Base64 используется для компактного представления бинарных данных в текстовом виде.

Кодирование

var bits = sjcl.codec.utf8String.toBits("crypto");
var b64 = sjcl.codec.base64.fromBits(bits);

Результат:

Y3J5cHRv

Декодирование

var bits = sjcl.codec.base64.toBits("Y3J5cHRv");
var text = sjcl.codec.utf8String.fromBits(bits);

Base64URL кодек

Отличие от стандартного Base64:

  • + заменяется на -
  • / заменяется на _
  • отсутствует padding =

Используется в токенах, URL и JWT-подобных структурах.

Пример кодирования

var bits = sjcl.codec.utf8String.toBits("data");
var urlsafe = sjcl.codec.base64url.fromBits(bits);

Декодирование

var bits = sjcl.codec.base64url.toBits(urlsafe);
var text = sjcl.codec.utf8String.fromBits(bits);

Внутренний формат и потеря контекста

При преобразованиях важно учитывать:

  • UTF-8 кодек работает с символами
  • HEX и Base64 работают с байтовым представлением
  • bitArray не хранит тип данных, только биты

Пример потери семантики:

var bits = sjcl.codec.utf8String.toBits("1234");
var hex = sjcl.codec.hex.fromBits(bits);

Обратно:

var restored = sjcl.codec.utf8String.fromBits(
    sjcl.codec.hex.toBits(hex)
);

Результат сохраняется только при корректной последовательности преобразований.


Цепочки преобразований

SJCL часто используется в цепочках вида:

Строка → шифрование → Base64

var key = sjcl.codec.utf8String.toBits("password");
var data = sjcl.codec.utf8String.toBits("secret message");

var encrypted = sjcl.encrypt("password", "secret message");

var parsed = JSON.parse(encrypted);

Здесь внутри encrypt автоматически используется:

  • UTF-8 → bitArray
  • AES обработка
  • Base64 сериализация

Работа с бинарными данными

Для работы с произвольными байтами часто используется HEX как промежуточный формат.

Генерация случайных данных

var bits = sjcl.random.randomWords(4);
var hex = sjcl.codec.hex.fromBits(bits);

Использование в криптографии

var key = sjcl.codec.hex.toBits("00112233445566778899aabbccddeeff");

Особенности преобразования длины

bitArray хранит длину в битах, что влияет на:

  • обрезку последних байтов
  • восстановление строк
  • корректность padding

Пример:

var bits = sjcl.codec.utf8String.toBits("a");

Это не просто 1 символ, а:

  • 8 бит данных
    • служебная длина

Сравнение кодеков по назначению

Кодек Назначение Особенности
UTF-8 текст работа с символами
HEX байты в строке читаемость
Base64 компактное хранение стандарт бинарных данных
Base64URL URL-safe формат без padding

Ошибки при преобразованиях

Типичные проблемы:

1. Потеря кодировки

sjcl.codec.hex.toBits("zzzz"); // ошибка

HEX требует корректных символов 0-9, a-f.


2. Неверный тип входных данных

sjcl.codec.base64.toBits(12345);

Кодек ожидает строку, а не число.


3. Несоответствие кодеков

sjcl.codec.hex.toBits(
    sjcl.codec.base64.fromBits(bits)
);

Без промежуточного перевода результат будет некорректным.


Преобразования в криптографических сценариях

Типичный поток данных:

  1. Текст
"message"
  1. UTF-8
sjcl.codec.utf8String.toBits(...)
  1. Шифрование AES
sjcl.encrypt(key, message)
  1. Base64 упаковка
JSON-структура с ciphertext

Обратное преобразование происходит в обратном порядке строго через соответствующие codec-методы.


Комбинирование кодеков

SJCL позволяет строить гибкие конвейеры:

var hex = sjcl.codec.hex.fromBits(
    sjcl.codec.utf8String.toBits("data")
);

var base64 = sjcl.codec.base64.fromBits(
    sjcl.codec.hex.toBits(hex)
);

Каждый шаг превращает представление, но не теряет исходные биты при корректной цепочке.


Практическое значение bitArray как универсального слоя

Кодеки в SJCL выполняют не просто преобразование форматов, а роль адаптеров между:

  • человекочитаемым текстом
  • бинарными структурами
  • криптографическими алгоритмами

bitArray является точкой консолидации всех этих представлений, а codec — механизмом входа и выхода из криптографического ядра библиотеки.