Сериализация данных в информатике¶
Сериализация — это процесс преобразования структуры данных (объектов, деревьев состояний) в формат, пригодный для последующего хранения или передачи по каналам связи, с возможностью обратного восстановления (десериализации). Сериализованный поток байтов или символов должен однозначно кодировать исходное состояние объекта, включая значения полей и типы данных. Термин широко применяется в информатике, программной инженерии и информационной безопасности.
¶Назначение
Сериализация решает несколько практических задач:
- Персистентность — сохранение состояния программы между запусками (сериализация в файл или базу данных).
- Межпроцессное взаимодействие — передача данных между независимыми процессами, в том числе по сети.
- Сетевые протоколы — формат обмена сообщениями между клиентом и сервером (SOAP, REST с JSON, gRPC с Protocol Buffers).
- Кэширование — сохранение вычисленных результатов для повторного использования.
- Создание снимков состояния — бэкапы, откат транзакций, отладочные дампы.
¶Основные подходы
¶Бинарная сериализация
Преобразует данные в компактный поток байтов. Отличается высокой скоростью работы и малым объёмом, но, как правило, не является переносимой между разными языками программирования и версиями приложений. Примеры: Java Serializable, .NET BinaryFormatter, Python pickle.
¶Текстовая сериализация
Использует человекочитаемые текстовые форматы. Основные достоинства — переносимость, отладочность, совместимость с широким кругом инструментов. Недостатки — больший объём и более низкая скорость парсинга по сравнению с бинарными форматами.
¶Основные форматы
| Формат | Тип | Описание |
|---|---|---|
| JSON | текстовый | Подмножество JavaScript; де-факто стандарт обмена данными в вебе |
| XML | текстовый | Расширяемый язык разметки; используется в SOAP, конфигурациях, документах |
| YAML | текстовый | Человекочитаемый формат с упором на компактность; популярен в конфигурациях |
| Protocol Buffers | бинарный | Формат Google; схема описывается в .proto, поддерживает эволюцию формата |
| MessagePack | бинарный | «Сжатый JSON»: те же структуры, но в бинарном виде |
| CBOR | бинарный | Стандарт IETF (RFC 8949), основан на модели данных JSON |
| BSON | бинарный | Формат MongoDB; расширяет JSON дополнительными типами |
| Avro | бинарный | Используется в экосистеме Apache Hadoop; схема хранится вместе с данными |
| FlatBuffers | бинарный | Доступ к данным без предварительного разбора; применяется в играх |
| ASN.1 | текстовый/бинарный | Стандарт ITU-T; лежит в основе X.509, SNMP, LTE-протоколов |
¶Проблемы совместимости
¶Версионирование
При изменении структуры объекта (добавлении, удалении или переименовании полей) ранее сохранённые данные могут стать нечитаемыми. Для решения этой проблемы форматы поддерживают механизмы эволюции схемы: необязательные поля (Protocol Buffers, Avro), версии документа (MongoDB), явные миграции (Rails ActiveRecord, Alembic для SQLAlchemy).
¶Циклические ссылки
Объекты, ссылающиеся друг на друга, могут привести к бесконечной рекурсии при обходе. Большинство библиотек либо отклоняют такие структуры, либо поддерживают механизм ссылок (Java writeObject/readObject, Python pickle).
¶Полиморфизм
Для корректной десериализации объекта производного класса поток должен содержать информацию о его точном типе. Решения варьируются от записи имени класса в поток (Java, .NET) до использования дискриминаторов (JSON с полем type).
¶Безопасность
Десериализация недоверенных данных представляет серьёзную угрозу. Ключевые риски:
- Выполнение произвольного кода — многие библиотеки (Java
ObjectInputStream, Pythonpickle, PHPunserialize) при разборе потока могут создавать объекты и вызывать методы, что позволяет злоумышленнику выполнить вредоносный код. Уязвимость входит в список OWASP Top 10. - Отказ в обслуживании — «бомбы десериализации»: компактные входные данные, разворачивающиеся в огромные структуры (например, «бомба XML-сущностей» — billion laughs).
- Обход проверок — подмена типа объекта для получения доступа к привилегированным операциям.
Для снижения рисков рекомендуется не десериализовать данные из недоверенных источников, использовать форматы без выполнения кода (JSON, Protocol Buffers), применять валидацию схемы и цифровые подписи.
¶Сериализация в языках программирования
- Java — интерфейс
java.io.Serializable, механизмыExternalizable, альтернативы: Jackson, Gson, Kryo. - Python — модули
pickle,json,marshal; сторонние:msgpack,protobuf. - C# / .NET —
System.Text.Json,Newtonsoft.Json,DataContractSerializer, устаревшийBinaryFormatter. - JavaScript — встроенный
JSON.stringify/JSON.parse; для объектов с циклами и специальными типами —structuredClone. - Go — стандартный пакет
encoding/json,encoding/gob,protobuf.
¶Связанные понятия
Сериализация тесно связана с понятием контейнера данных и формата обмена. Противоположная операция — десериализация (разбор, unmarshalling) — восстанавливает объект из потока. В контексте распределённых систем сериализация является основой для RPC-фреймворков (gRPC, Apache Thrift, Hessian) и систем потоковой обработки данных (Apache Kafka, Apache Flink).
Источники:
- RFC 8949. Concise Binary Object Representation (CBOR)
- OWASP Deserialization Cheat Sheet
- Bloch J. Effective Java (3rd ed.). — Addison-Wesley, 2018
- Gruber T. A. Specification of the JSON Data Interchange Format (RFC 8259)
- Documentation: Protocol Buffers Developer Guide, Google
- ГОСТ Р ИСО/МЭК 14888-3 — процедуры аутентификации, включая форматы подписанных сообщений
