Как перевести число из шестнадцатеричной системы в двоичную в 1С?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

В процессе разработки часто возникает необходимость преобразования данных между различными системами счисления. Особенно это актуально при работе с низкоуровневыми протоколами торгового оборудования, анализе штрихкодов или криптографических операциях. Одной из наиболее частых задач является конвертация из шестнадцатеричной (Hex) системы в двоичную (Binary). В этой статье мы подробно разберем, почему возникают ошибки при стандартном подходе и как реализовать надежный алгоритм на языке 1С.

Основы теории: почему 16-ричная и двоичная системы «родственные»

Прежде чем приступать к написанию кода, разберем теоретическую базу. Шестнадцатеричная система счисления имеет основание 16 (2 в четвертой степени). Это означает, что каждой цифре шестнадцатеричного числа (от 0 до F) соответствует ровно четыре знака (бита) в двоичной системе. Такая группа из 4 бит называется тетрадой.

Рассмотрим таблицу соответствия:

  1. 0 — 0000
  2. 1 — 0001
  3. ...
  4. 9 — 1001
  5. A — 1010
  6. B — 1011
  7. C — 1100
  8. D — 1101
  9. E — 1110
  10. F — 1111

Именно благодаря этому свойству перевод из Hex в Binary можно выполнять «в лоб» — просто заменяя каждый символ исходной строки соответствующей четверкой нулей и единиц. Это гораздо эффективнее и точнее, чем использование промежуточного преобразования в десятичное число.

Проблема промежуточной конвертации в десятичную систему

Многие начинающие программисты пытаются решить задачу через перевод Hex -> Dec -> Bin. Проанализируем ситуацию, когда этот метод дает сбой. В 1С тип Число ограничен 38 знаками. Если вам нужно перевести длинный идентификатор или GUID (например, 128-битный код), промежуточное десятичное число просто «не влезет» в переменную или потеряет точность. Кроме того, при математическом переводе часто теряются лидирующие нули, что критично для двоичных данных фиксированной длины.

Решение №1: Посимвольная замена (универсальный метод)

Наиболее надежный способ для работы со строками любой длины — это перебор каждого символа шестнадцатеричной строки. Рассмотрим пример функции, которая реализует этот алгоритм через оператор Если...ИначеЕсли. Этот метод гарантирует сохранение всех бит, включая ведущие нули каждой тетрады.


Функция ШестнадцатиричноеВДвоичное(Знач ВходнаяСтрока) Экспорт
    
    Стр = СокрЛП(ВходнаяСтрока);
    Результат = "";
    
    Для н = 1 По СтрДлина(Стр) Цикл
        Буква = Вверх(Сред(Стр, н, 1));
        
        Если Буква = "0" Тогда Результат = Результат + "0000";
        ИначеЕсли Буква = "1" Тогда Результат = Результат + "0001";
        ИначеЕсли Буква = "2" Тогда Результат = Результат + "0010";
        ИначеЕсли Буква = "3" Тогда Результат = Результат + "0011";
        ИначеЕсли Буква = "4" Тогда Результат = Результат + "0100";
        ИначеЕсли Буква = "5" Тогда Результат = Результат + "0101";
        ИначеЕсли Буква = "6" Тогда Результат = Результат + "0110";
        ИначеЕсли Буква = "7" Тогда Результат = Результат + "0111";
        ИначеЕсли Буква = "8" Тогда Результат = Результат + "1000";
        ИначеЕсли Буква = "9" Тогда Результат = Результат + "1001";
        ИначеЕсли Буква = "A" Тогда Результат = Результат + "1010";
        ИначеЕсли Буква = "B" Тогда Результат = Результат + "1011";
        ИначеЕсли Буква = "C" Тогда Результат = Результат + "1100";
        ИначеЕсли Буква = "D" Тогда Результат = Результат + "1101";
        ИначеЕсли Буква = "E" Тогда Результат = Результат + "1110";
        ИначеЕсли Буква = "F" Тогда Результат = Результат + "1111";
        КонецЕсли;
    КонецЦикла;
    
    Возврат Результат;
    
КонецФункции

Важный момент: если вы используете результат для вычислений, вам может потребоваться убрать лишние нули в самом начале итоговой строки. Однако для передачи данных в оборудование обычно требуется именно полная строка с сохранением разрядности.

Решение №2: Оптимизация через объект «Соответствие»

Если планируется обрабатывать большие объемы данных, постоянное выполнение условий ИначеЕсли может замедлить работу. Проанализируем более изящный способ — использование объекта Соответствие. Мы один раз инициализируем таблицу перевода в памяти, а затем мгновенно получаем значение по ключу.


Функция HexToBinaryFast(Знач СтрHex) Экспорт
    
    ТаблицаТетрад = Новый Соответствие;
    ТаблицаТетрад.Вставить("0", "0000"); ТаблицаТетрад.Вставить("1", "0001");
    ТаблицаТетрад.Вставить("2", "0010"); ТаблицаТетрад.Вставить("3", "0011");
    ТаблицаТетрад.Вставить("4", "0100"); ТаблицаТетрад.Вставить("5", "0101");
    ТаблицаТетрад.Вставить("6", "0110"); ТаблицаТетрад.Вставить("7", "0111");
    ТаблицаТетрад.Вставить("8", "1000"); ТаблицаТетрад.Вставить("9", "1001");
    ТаблицаТетрад.Вставить("A", "1010"); ТаблицаТетрад.Вставить("B", "1011");
    ТаблицаТетрад.Вставить("C", "1100"); ТаблицаТетрад.Вставить("D", "1101");
    ТаблицаТетрад.Вставить("E", "1110"); ТаблицаТетрад.Вставить("F", "1111");
    
    Результат = "";
    Для Позиция = 1 По СтрДлина(СтрHex) Цикл
        Символ = Вверх(Сред(СтрHex, Позиция, 1));
        ДвоичныйЭквивалент = ТаблицаТетрад.Получить(Символ);
        Если ДвоичныйЭквивалент <> Неопределено Тогда
            Результат = Результат + ДвоичныйЭквивалент;
        КонецЕсли;
    КонецЦикла;
    
    Возврат Результат;
    
КонецФункции

Решение №3: Математический подход (для небольших чисел)

Выясним ситуацию, когда нам всё же нужно работать через десятичное число. Это удобно, если число гарантированно умещается в стандартный тип Число. В современных версиях платформы 1С (8.3.10+) появились встроенные функции ЧислоИзШестнадцатеричнойСтроки и ПолучитьДвоичнуюСтрокуИзЧисла. Посмотрим, как их скомбинировать.


Функция КонвертироватьЧерезПлатформу(Знач HexСтрока)
    // Преобразуем Hex в десятичное число
    ДесятичноеЧисло = ЧислоИзШестнадцатеричнойСтроки(HexСтрока);
    
    // Преобразуем число в двоичную строку
    // Второй параметр позволяет задать минимальную длину строки (например, 8, 16, 32)
    Возврат ПолучитьДвоичнуюСтрокуИзЧисла(ДесятичноеЧисло);
КонецФункции

Обратите внимание: встроенная функция ПолучитьДвоичнуюСтрокуИзЧисла по умолчанию не добавляет ведущие нули до тетрад, она возвращает минимально необходимую строку. Если вам нужно строгое соответствие 1 символ Hex = 4 символа Bin, используйте первые два метода.

Типичные ошибки при конвертации

Разберем основные грабли, на которые наступают разработчики:

  1. Регистр символов: Символы "a" и "A" в шестнадцатеричной системе идентичны. Всегда приводите входящую строку к верхнему регистру функцией Вверх() или НРег()/ВРег() перед поиском.
  2. Лидирующие нули: Число 0x0F в двоичной системе — это 00001111. Математический метод может вернуть просто 1111, потеряв первые четыре нуля. Это критично, если вы формируете пакет данных для отправки по TCP/IP или в COM-порт.
  3. Пробелы и спецсимволы: В начале или конце строки могут быть невидимые символы. Всегда используйте СокрЛП() перед обработкой.

Подводя итог, можно сказать, что для большинства задач в 1С наиболее предпочтительным является метод посимвольной замены (Решение №1 или №2). Он прост в отладке, не зависит от разрядности платформы и гарантирует побитовую точность преобразования.

← На главную