Как уменьшить количество символов во внутреннем идентификаторе (GUID) 1С до 17 символов?

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

В процессе интеграции 1С с внешними информационными системами (ИС) разработчики часто сталкиваются с жесткими ограничениями на длину полей. Стандартный внутренний идентификатор 1С (UUID/GUID) представляет собой 128-битное число, которое в строковом виде занимает 36 символов (с дефисами) или 32 символа (без дефисов). Если принимающая система ограничивает длину кода, например, 17 символами, стандартный подход передачи УникальныйИдентификатор() перестает работать. В этой статье мы разберем несколько стратегий решения этой задачи: от математического сжатия до использования особенностей структуры идентификаторов 1С.

Понимание структуры GUID в 1С

Прежде чем приступать к сокращению, проанализируем, что представляет собой идентификатор 1С. Платформа использует GUID версии 1 (V1), который формируется на основе текущего времени (с точностью до 100 наносекунд) и MAC-адреса сетевой карты сервера. Рассмотрим стандартный вид: d6c20ebd-0276-11db-8007-0013d4609ea4.

Важные моменты:

  1. Временная составляющая: Первые три группы символов (8-4-4) отвечают за время. В 1С версии 8 порядок байтов специфичен: младшие части времени могут находиться в конце или начале в зависимости от метода генерации, но для объектов, созданных в одной базе подряд, значительная часть GUID будет меняться предсказуемо.
  2. MAC-адрес: Последняя группа из 12 символов — это идентификатор узла (сервера). Если все объекты создаются на одном сервере, эта часть будет идентичной для тысяч записей.

Проанализируем ситуацию: если нам нужно обеспечить уникальность только внутри нашей базы для 3-5 тысяч записей, передавать MAC-адрес сервера избыточно. Мы можем использовать только «динамическую» часть идентификатора.

Метод 1: Изменение системы счисления (BaseN)

Стандартный GUID записан в 16-ричной системе (Hex). Чтобы уменьшить количество символов без потери информации, нам нужно перейти к системе счисления с большим основанием. Рассмотрим математическую прогрессию:

Однако использование системы с основанием 185 и выше требует применения спецсимволов и Unicode, что часто неприемлемо для ИС-приемников. Если же мы готовы пожертвовать избыточностью (например, отбросить статичную часть MAC-адреса), то Base62 идеально подходит. Рассмотрим программную реализацию перевода числа из одной системы в другую.

Для реализации этого метода воспользуемся функциями преобразования:


// Функция преобразует значение из одной системы счисления в другую
Функция AnyToAny(Знач ЗначениеСтр, АлфавитИсточник, АлфавитПриемник)
    Возврат DecToAny(AnyToDec(ЗначениеСтр, АлфавитИсточник), АлфавитПриемник);
КонецФункции

Функция AnyToDec(Знач ЗначениеСтр, Т)
    Результат = 0;
    Основание = СтрДлина(Т);
    Длина = СтрДлина(ЗначениеСтр);
    Для i = 0 По Длина - 1 Цикл
        Символ = Сред(ЗначениеСтр, Длина - i, 1);
        Позиция = СтрНайти(Т, Символ) - 1;
        Результат = Результат + Позиция * Pow(Основание, i);
    КонецЦикла;
    Возврат Результат;
КонецФункции

Функция DecToAny(Знач ЧислоДесятичное, Т, Длина = 0)
    Результат = "";
    Основание = СтрДлина(Т);
    Пока ЧислоДесятичное > 0 Цикл
        Остаток = ЧислоДесятичное % Основание;
        Результат = Сред(Т, Остаток + 1, 1) + Результат;
        ЧислоДесятичное = Цел(ЧислоДесятичное / Основание);
    КонецЦикла;
    
    Пока СтрДлина(Результат) < Длина Цикл
        Результат = Лев(Т, 1) + Результат;
    КонецЦикла;
    
    Возврат Результат;
КонецФункции

Используя этот подход, мы можем взять первые 16-20 символов GUID (без дефисов) и сжать их в 10-12 символов Base62, что гарантированно уместится в лимит 17 символов.

Метод 2: Выделение уникальной части (Truncation)

Как мы выяснили при анализе структуры, для небольших справочников (до 10-50 тысяч записей) первые три сегмента GUID обеспечивают достаточную уникальность. Рассмотрим пример: вместо полного d6c20ebd-0276-11db-8007-0013d4609ea4 мы берем только d6c20ebd027611db (16 символов).

Почему это работает? В GUID V1 эти сегменты содержат временную метку. Вероятность того, что два разных объекта в 1С получат одинаковую метку времени в этих разрядах, крайне мала, если только они не создаются на разных серверах в одну и ту же наносекунду с последующим слиянием баз.

Проанализируем ситуацию программно:


// Получение сокращенного идентификатора
ПолныйУИД = Строка(СсылкаНаОбъект.УникальныйИдентификатор());
СокращенныйУИД = СтрЗаменить(Лев(ПолныйУИД, 18), "-", ""); // Получаем 16 символов

Метод 3: Использование Хеширования

Если нам не нужно восстанавливать исходный GUID из сокращенного кода, мы можем применить хеш-функцию, например MD5 или CRC64. Хеш MD5 выдает 128 бит (32 символа в Hex), что опять же много. Однако CRC64 дает 64 бита, которые в системе Base62 преобразуются в 11 символов.

Важно помнить: хеш-функция теоретически допускает коллизии (разные GUID могут дать одинаковый хеш). Но для объема данных в несколько тысяч записей при использовании 64-битного хеша вероятность коллизии стремится к нулю.

Метод 4: Регистр соответствий (Самый надежный)

Если бизнес-процесс критичен к уникальности и вы не хотите полагаться на математические вероятности, следует использовать Регистр сведений. Это классический архитектурный паттерн в 1С для обмена данными.

Алгоритм действий:

  1. Создаем регистр сведений СоответствиеОбъектовДляОбмена.
  2. Добавляем измерения: Объект (Тип: ЛюбаяСсылка) и ИдентификаторИС (Тип: Строка 17).
  3. При первой выгрузке генерируем случайную строку или последовательное число (счетчик) длиной до 17 символов.
  4. Записываем связь в регистр.
  5. При последующих выгрузках берем готовый код из регистра.

Этот метод позволяет полностью избежать «кракозябр» и математических проблем, обеспечивая 100% стабильность обмена, хотя и требует небольшого изменения конфигурации (добавления одного регистра).

Резюме

Выясним причину выбора конкретного метода:

Рассмотренные способы позволяют гибко подойти к ограничениям внешних систем, сохраняя при этом целостность данных при обмене из 1С.

← На главную