CJON v1.1 (Compact JSON)
Введение
С каждым витком развития информационных технологий мы все больше зависим от них. Неблагоприятные события и масштабные инциденты в области связи, кибербезопасности и т.п. обнажают нашу зависимость от технологий и беспомощность при её исчезновении. В современной России мы часто сталкиваемся с условиями ограниченной доступности телекоммуникационных технологий в том числе блокировка мобильного Интернета. При этом iot-устройства, датчики и мобильные приложения требуют для их работы возможности передачи данных. Например, отсутствие Интернета делает невозможным заказ Яндекс-такси, передачи данных с метеостанции в поле, снятие показаний устройств умного дома загородом.
Для решения описанной проблемы предлагается использование резервного канала в виде SMS-сообщений, передачи данных посредство DTMF (Dual-Tone Multi-Frequency - технология тонального набора номера, используемая в телефонах и других устройствах для передачи цифровой информации по телефонным линиям). Предлагается использовать голосовые и SMS-каналы сотовой сети (включая 2G) как резервный транспорт для передачи данных на сервер, который имеет стабильное Интернет-соединение. Для упаковки данных в приемлемый компактный вид предлагается следующее решение.
1. Назначение
CJON - это легковесный, компактный и человекочитаемый формат, предназначенный для использования в условиях ограниченных каналов связи, таких как SMS, DTMF, и низкоскоростные и устаревшие каналы связи (например, 2G, голос, радиоканал). Его основное назначение - передача структурированных телеметрических или управляющих данных в случаях, когда традиционный JSON слишком объёмен, а бинарные форматы непрактичны или плохо читаемы.
2. Области применения
Дистанционная телеметрия для сельского хозяйства и промышленного оборудования;
- Аварийные сообщения и тревоги;
- Автоматизация в условиях низкоскоростной или оффлайн-связи;
- Мобильные устройства, передающие структурированные данные через SMS или голосовую связь;
- Передача данных по DTMF через GSM-сети.
3. Обзор синтаксиса
Сообщение CJON состоит из последовательности элементов, разделённых точками с запятой (;).
- Первый элемент - тип сообщения (обязателен, без ключа), например: T1;
- Остальные элементы - пары ключ=значение или значения через запятую для массивов.
Пример запроса для такси (f - from массив координат точки, to - массив координат точки назначения, r- тариф):
T1;f=56.3365,36.7259;to=56.1843,36.9745;r=2
4. Формат записи значений
Строка RAW (текст без base64)
Используется алфавит GSM 7‑bit (базовое подмножество ASCII) без зарезервированных символов CJON.
- Разрешены: латиница A-Z, a-z, цифры 0-9, пробел и безопасная пунктуация !"#$%&'()*+-./:<>?@.
- Запрещены в RAW: разделители и служебные символы ; = , { } ~ и управляющие 0x00–0x1F, 0x7F.
Символ @ разрешён внутри строки (например, для e‑mail), но не может быть первым символом значения, чтобы не конфликтовать с маркером времени.
Пример:
note=station west gate
email=user@stukalin.com
Строка в base64
Если значение содержит запрещённые символы (в т.ч. запятую, фигурные скобки, нелатиницу, переносы строк), оно кодируется в base64 и записывается с префиксом ~ вместо =:
msg~0KHRgtGD0LrQsNC70LjQvSDQkNC70LXQutGB0LXQuQ==
Число (целое или с плавающей точкой)
a=123
temp=21.7
Дата/время как Unix timestamp - префикс @ вместо =
ts@1725609120 (2024-09-06T12:32:00Z)
* Дата без времени (ISO 8601, YYYY-MM-DD) * - префикс ^ вместо =
start^2024-09-06
Массив значений - список через запятую (интерпретируется как массив примитивов)
tags=alpha,beta,gamma
loc=56.3365,36.7259
Если нужна "настоящая" запятая внутри строки - используется base64
Примечание. Кавычки и скобки для значений не используются: это экономит объём и упрощает парсинг. Тип значения в CJON определяется по символу сразу после ключа:
= - RAW/число; ~ - base64; @ - timestamp; ^ - дата ISO.
Поддержка вложенности
CJON поддерживает вложенные объекты двумя способами - выбирается тот, что короче:
- Точечная нотация ключей (удобно, когда значений немного):
d.id=agro-007;d.b.v=3.7;d.b.s=ok;l.lat=56.3284;l.lon=37.4921;e.temp=23.5;e.hum=61
- Блочная нотация с фигурными скобками (компактнее для групп полей):
d{id=agro-007;b{v=3.7;s=ok}};l{lat=56.3284;lon=37.4921};e{temp=23.5;hum=61}
Парсер обязан корректно понимать обе нотации и считать их эквивалентными. Для массивов объектов используется блочная форма без индексов:
ev{{t=start;c=1};{t=stop;c=2}}
а массивы примитивов — через запятую, как выше.
5. Сравнение CJON и JSON
CJON устраняет кавычки, скобки и пробелы, тем самым экономя от 30% до 50% символов;
Пример JSON (398 символов) -> аналогичный CJON (287 символов): экономия 111 символов (~28%).
6. Сравнение с существующими подходами
Существует ряд форматов и методов, разработанных с целью сократить объём JSON-данных, особенно в условиях ограниченных каналов связи (например, в IoT, мобильных или встраиваемых системах). Ниже приведён краткий обзор таких подходов.
Бинарные форматы
MessagePack (msgpack.org) - бинарный формат сериализации, который кодирует JSON в компактный бинарный вид. Даёт сокращение на 30-60% по сравнению с обычным JSON. Используется в высокопроизводительных API, но не подходит для текстовых каналов связи (SMS, голос, DTMF);
CBOR (Concise Binary Object Representation) (cbor.io) - формат от IETF, используемый в CoAP и других IoT-протоколах. Обеспечивает высокую степень сжатия, поддерживает теги и расширенные типы данных. Требует парсера на стороне приёмника;
UBJSON / BSON / Smile - бинарные альтернативы JSON, ориентированные на специфические платформы (MongoDB, Java и др.). Не применимы в условиях, где требуется текстовая передача или совместимость с низкоуровневыми каналами.
Текстовые форматы
MinJSON / SlimJSON... - неформальные минималистичные текстовые форматы, в которых устраняются пробелы и кавычки, ключи заменяются на короткие, и используется нестандартный синтаксис. Подходы разрозненные, не стандартизированы, вложенность не поддерживается.
YAML Flow Style - почти тоже самое, что и мой формат и вполне можно было бы обойтись им, но CJON капельку проще и короче, а мы считаем каждый байт.
7. Расширенная вложенность (оптимизация через блоки)
Для дополнительного сокращения объема сообщения в случае передачи вложенных словарей (объектов), CJON допускает альтернативный способ представления вложенности с помощью фигурных скобок {};
Вместо того чтобы сериализовать каждый элемент вложенного объекта через точечную нотацию, например:
batt.voltage=3.7;batt.status=ok
можно использовать вложенный блок, если он оказывается более компактным:
batt{voltage=3.7;status=ok}
Правила применения:
Блоки могут быть вложены на любую глубину;
Допустимо чередование точечной и блочной нотации;
Внутри фигурных скобок допускается та же структура ключ=значение; с разделителями ";";
Символы { и } становятся зарезервированными и требуют экранирования (или кодирования BASE64) внутри значений, если используются как часть строки;
Парсеры CJON должны быть способны различать как a.b=1, так и a{b=1} и обрабатывать их как эквивалентные формы.
Пример:
S1;device{id=agro-007;batt{voltage=3.7;status=ok}};env{temp=22.5;hum=60}
Эквивалент в точечной нотации:
S1;device.id=agro-007;device.batt.voltage=3.7;device.batt.status=ok;env.temp=22.5;env.hum=60
Для сериализации вложенных объектов CJON-парсер может автоматически выбирать между блочной и точечной нотацией в зависимости от итоговой длины строки: используется тот формат, который экономит больше символов.
Заключение
CJON представляет собой структурированный, но компактный формат, являющийся альтернативой громоздким форматам, таким как JSON или XML, в условиях ограниченных ресурсов. Он обеспечивает баланс между читаемостью, простотой обработки и экономией трафика, что делает его идеальным для маломощных, низкоскоростных или устаревших систем. При кодировании JSON-файлов, имеющих большое количество вложенных объектов и текстовых данных, CJON может быть сопоставим или даже превышать кодируемый JSON по объёму из-за использования base64 или вложенных объектов, но при этом сохраняет преимущества в каналах связи и сохраняет совместимость для применения формата в SMS. Незначительное увеличение размера структуры нивелируется тем, что закодированные структуры отправляются в формате GSM 7-bit, против UCS-2 (UTF-16).