Bencode-кодирование
Bencode (произносится как "Bee-Encode") — это формат для хранения и передачи любых структурированных данных в BitTorrent. Поддерживаются следующие типы данных:
- целые числа;
- строки байтов;
- списки;
- словари (ассоциативные массивы).
Bencode-кодирование используется в .torrent файлах. Это файлы метаданных и по сути являются просто закодированными словарями. Данные, которые посылает клиенту трекер, также преобразовываются в bencode.
Несмотря на то что при bencode-кодировании информация храниться в текстовом формате, а не в виде бинарнарных данных (и соответственно занимает больший объем) — bencode-кодирование все же имеет ряд преимуществ. Так например, числа кодируются в десятичной системе счисления и их представление не зависит от порядка следования байт, что важно для кроссплатформенных приложений. Также, приложения могут просто игнорировать неизвестные им ключи словарей, что делает добавление новых параметров более гибким и позволяет избежать проблем с совместимостью разных версий.
Алгоритм кодирования
Все символы разделителей и цифр, используемые при bencode-кодировании и указанные в правилах ниже — это ASCII-символы. Правила кодирования для каждого типа данных:
- Целое число
i<число в десятичной системе счисления>e. Целые числа не имеют ограничений по размеру. Отрицательные значения кодируются добавлением в начале числа знака минус, но при этом запрещено использование в начале числа нулей (конечно же кроме самого числа ноль). Например число 42 кодируется какi42e, -42 какi-42eи ноль какi0e. Неверные значения:i-0eилиi042e.- Строка байтов
<длина>:<содержимое>. Строка байтов — это последовательность символов (не обязательно печатных). Длина кодируется положительным десятичным числом или нулем. Содержимое — это байты, которые формируют строку. Строка «spam» кодируется как4:spam. Спецификация не определяет способ кодирования символов не входящих в набор ASCII. Чтобы как-то это исправить, некоторые BitTorrent-приложения явно сообщают кодировку (чаще всего это UTF-8) различными не стандартными способами.- Список значений
l<содержимое>e. Содержимое состоит из bencode-кодированных элементов списка, отсортированных и объединенных вместе. Список, состоящий из строки «spam» и числа 42:['spam', 42]— кодируется какl4:spami42ee. Обратите внимание на отсутствие разделителей между элементами.- Словарь
d<содержимое>e. Элементы словаря кодируются и объединяются вместе. Каждое значение следует непосредственно за ключом, связанным с ним. Все ключи должны быть строками байт, и быть отсортированы в лексикографическом порядке. Словарь, связывающий значения 42 и «spam» с ключами «foo» и «bar» соответственно, кодируется следующим образом:d3:bar4:spam3:fooi42ee(Для большей наглядности можно вставить несколько пробелов:d 3:bar 4:spam 3:foo i42e e).
В списках и словарях нет никаких ограничений на тип хранимых значений. Они могут (и обычно так и есть) содержат другие списки и словари. Это позволяет кодировать сложные структуры данных.
Дополнительная информация
- Для любого возможного (сколь угодно сложного) значения есть только одно единственное правильное bencode-значение. Т.е. существует взаимно однозначное соответствие между значениями и их кодированным представлением. Это дает возможность приложениям сравнивать bencode-кодированные значения не применяя декодирование.
- Хотя большинство закодированных значений могут быть легко декодированы человеком «вручную», все же с ростом сложности структуры данных и с увеличением объема бинарных данных — ухудшается и читаемость вencode-кода.
- Bencode-кодирование выполняет ту же функцию что и языки разметки XML и JSON — позволяет хранить данные со сложной структурой без привязки к какой-либо платформе.