При интеграции 1С с внешними сервисами, почтовыми протоколами (например, при формировании заголовков вроде Thread-Index) или низкоуровневыми API часто возникает необходимость работать с «сырыми» байтами: перевести шестнадцатеричную (Hex) строку в массив байтов, дополнить произвольными байтами, получить представление в Base64 или сохранить результат напрямую в файл.
Разберем типичные ошибки при решении этой задачи, а также рассмотрим по шагам все правильные и эффективные способы работы с двоичными данными в платформе 1С:Предприятие.
Проанализируем частую ошибку начинающих разработчиков: попытку собрать бинарную строку через конкатенацию вида Символ(КодБайта) и сохранить её с помощью объекта ЗаписьТекста. Этот подход приводит к искажению данных по нескольким причинам:
0 (символ NUL) и другие управляющие символы могут некорректно обрабатываться строковыми функциями платформы.Для работы с байтами следует применять специализированные объекты платформы: БуферДвоичныхДанных, ДвоичныеДанные, ПотокВПамяти и ЗаписьДанных.
Рассмотрим самый быстрый и лаконичный путь. Начиная с версии платформы 8.3.10, в глобальном контексте доступны встроенные методы, которые позволяют преобразовывать Hex-строки и буферы данных в Base64 буквально в одну строку без циклов и ручного парсинга.
Посмотрим на пример, когда нужно взять Hex-строку, добавить к ней несколько байтов и получить итоговый Base64:
// Исходная шестнадцатеричная строка (без префиксов)
HexСтрока = "01020380FF";
// Получаем исходный буфер сразу из Hex
БуферИсходный = ПолучитьБуферДвоичныхДанныхИзHexСтроки(HexСтрока);
// Создаем буфер для дополнительных случайных байт (например, 5 байт)
БуферДобавка = Новый БуферДвоичныхДанных(5);
ГСЧ = Новый ГенераторСлучайныхЧисел;
Для Сч = 0 По 4 Цикл
БуферДобавка[Сч] = ГСЧ.СлучайноеЧисло(0, 255);
КонецЦикла;
// Объединяем буферы
БуферИтоговый = Новый БуферДвоичныхДанных(БуферИсходный.Размер + БуферДобавка.Размер);
БуферИсходный.Прочитать(0, БуферИтоговый, 0, БуферИсходный.Размер);
БуферДобавка.Прочитать(0, БуферИтоговый, БуферИсходный.Размер, БуферДобавка.Размер);
// Получаем строку Base64 напрямую из буфера
РезультатBase64 = ПолучитьBase64СтрокуИзБуфераДвоичныхДанных(БуферИтоговый);
Если дополнять данные не требуется, а нужно только преобразовать Hex в Base64, весь код сводится к одной операции:
ДвоичныеДанныеИзHex = ПолучитьДвоичныеДанныеИзHexСтроки(HexСтрока);
РезультатBase64 = Base64Строка(ДвоичныеДанныеИзHex);
Разберем классический алгоритм, когда необходимо побайтово обработать массив чисел от 0 до 255 и сформировать из него двоичные данные. Для этого создается объект БуферДвоичныхДанных заданного размера, после чего он заполняется по индексам (индексация буфера начинается с 0).
Посмотрим на реализацию функции преобразования:
Функция ПреобразоватьМассивБайтовВBase64(МассивБайтов)
// Создаем буфер нужной длины
Буфер = Новый БуферДвоичныхДанных(МассивБайтов.Количество());
// Заполняем буфер байтами
Для Сч = 0 По МассивБайтов.Количество() - 1 Цикл
Буфер[Сч] = МассивБайтов[Сч];
КонецЦикла;
// Получаем ДвоичныеДанные напрямую из буфера
ДвоичныеДанные = ПолучитьДвоичныеДанныеИзБуфераДвоичныхДанных(Буфер);
// Преобразуем в Base64
Возврат Base64Строка(ДвоичныеДанные);
КонецФункции
Обратите внимание: для получения объекта типа ДвоичныеДанные из буфера нет необходимости использовать объект ПотокВПамяти и вызывать метод ЗакрытьИПолучитьДвоичныеДанные(). Штатный метод ПолучитьДвоичныеДанныеИзБуфераДвоичныхДанных() выполняет эту задачу напрямую.
Если база работает на версиях платформы ниже 8.3.10, где глобальные функции для работы с Hex еще отсутствовали, проанализируем удобный способ конвертации с использованием типа схемы XML hexBinary. Это позволяет избежать ручного посимвольного перевода чисел из 16-ричной системы в 10-ричную:
Функция HexВBase64ЧерезXDTO(HexСтрока)
ТипHexBinary = ФабрикаXDTO.Тип("http://www.w3.org/2001/XMLSchema", "hexBinary");
ОбъектXDTO = ФабрикаXDTO.Создать(ТипHexBinary, HexСтрока);
// Свойство Значение автоматически возвращает объект ДвоичныеДанные
ДД = ОбъектXDTO.Значение;
Возврат Base64Строка(ДД);
КонецФункции
Выясним, как сохранить бинарные данные на диск без повреждения их структуры. В зависимости от задачи можно выбрать один из трех вариантов:
Самый простой и рекомендуемый способ, если данные уже находятся в переменной типа ДвоичныеДанные.
ДД = ПолучитьДвоичныеДанныеИзБуфераДвоичныхДанных(Буфер);
ДД.Записать("C:\temp\output.bin");
Удобно использовать для последовательной записи буферов в поток файла.
Запись = Новый ЗаписьДанных("C:\temp\output.bin");
Запись.Записать(Буфер);
Запись.Закрыть();
Подходит при работе с большими объемами данных и необходимости контролировать смещение или режим открытия файла.
ПотокФайла = ФайловыеПотоки.Открыть("C:\temp\output.bin", РежимОткрытияФайла.Создать, ДоступКФайлу.Запись);
ПотокФайла.Записать(Буфер, 0, Буфер.Размер);
ПотокФайла.Закрыть();
Использование специализированных типов данных платформы 1С гарантирует корректность бинарной структуры, отсутствие лишних маркеров кодировок и максимальное быстродействие при обработке массивов байтов.