Кодирование по алфавиту. Большие целые числа

22.05.20

Разработка - Защита ПО и шифрование

А вы знали, что 1С умеет в очень длинные числа? Кодирование информации в строку по указанному алфавиту, возможен любой алфавит и не только. В тексте приведён алгоритм для кодирования последовательности байт в любой и из любого односимвольного алфавита.

Скачать файлы

Наименование Файл Версия Размер
Кодирование по алфавиту:
.epf 8,19Kb
22
.epf 1.0 8,19Kb 22 Скачать бесплатно

Алгоритм позволяет кодировать двоичные данные по любому алфавиту, который можно представить в виде строки в поле ввода формы 1С:Предприятие.

На разработку этого решения меня натолкнула публикация: //infostart.ru/public/1153292/ В ней автор решал локальную задачу кодирования и раскодирования последовательности байтов в строку base-58. Исследовав вопрос кодирования, я решил провести эксперимент, какая же максимальная длина целого числа может быть представлена в 1С:Предприятии, чтобы не заниматься перемещением/умножением байтов. Точный ответ на этот вопрос я не получил, потому что умножение действительно длинных целых чисел происходит медленно, но стало ясно, что ограничение, если оно и есть, довольно велико, и для кодирования коротких последовательностей байтов, например ключей, вполне подходит.

Причём, когда-то эта тема уже исследовалась: https://forum.mista.ru/topic.php?id=608985 и там после 2^200 происходил "сбой" в арифметике. В релизе платформы для windows 8.3.16.1296 и 64х и 32х битном можно получать большие степени числа 2, другие релизы и на других платформах я не проверял.
 

Особенности реализации
Итак, платформа позволяет обрабатывать Большие целые числа. Попробуйте написать простую обработку, в обработке:

Сообщить(pow(2,1024*1024));


Так почему бы не воспользоваться.
Кодирование информации в строку по указанному алфавиту, с такими возможностями гораздо проще, умножай на размер алфавита каждый входящий символ при раскодировании и всё. А при кодировании каждый входящий байт на 256. Возможен любой алфавит. Нет необходимости перебирать байты и их двигать, умножать и т.п. когда 1С:Предприятие 8 позволяет оперировать со сколь угодно большими целыми числами. По крайней мере 2 в степени 1048576 позволяет получить, а это же 1048576 битное число, 128 килобайт данных можно передать таким числом.
Таким образом представляется возможным кодировать короткие сообщения напрямую умножая байты и получая остатки от деления на длину целевого алфавита.
Однако время на работу с длинными числами может быть весьма велико. Так, для кодирования в base-58 произвольной последовательности байт длиной 32768, требуется 4,5 секунды. Правда при этом вставка текста с Hex строкой длиной 65536 символов в поле ввода обработки происходит порядка 30 секунд.

Реализация алгоритма

В представленном коде имеются следующие функции:

КодироватьHex - кодирует строку Hex в строку по переданному алфавиту. Первый параметр - Hex строка, Второй - строка с символами алфавита. Нужна для удобства работы с обработкой и ввода байт в виде hex строки. Вызывает обработку Кодировать. Возвращает строку символов в кодировке алфавита.
Кодировать - кодирует двоичные данные по переданному алфавиту.

РаскодироватьHex - раскодирует строку символов по переданному алфавиту. Первый параметр - кодированная строка, второй - строка с символами алфавита. Вызывает функцию Раскодировать с теми же параметрами, но преобразует возвращаемые двоичные данные в hex строку, для удобства восприятия в обработке.

Функция ЛогарифмПоОснованию считает логарифм по произвольному основанию и позволяет примерно посчитать соотношение длины входных и выходных данных. При расшифровке входящей строки, нужно оценить каких размеров буфер двоичных данных создавать. Это можно сделать представив, что двоичные данные это тоже алфавит, состоящий из 256 "символов", а значит один и тот же объём информации в нём можно закодировать с использованием меньшего (или большего, если реализовать двухсимвольный например алфавит) числа "символов", чем во входящей строке. Соотношение между требуемым количеством символов можно записать как a^x=b, где a - число символов алфавита входной строки, b - число символов "выходной строки" - последовательности байтов. А x - коэффициент, в степень которого нужно возвести a чтобы получить b. Его можно вычислить как логарифм b по основанию а. Но средствами языка 1С можно получить только десятичный и натуральный логарифм. Поэтому получение логарифма по требуемому нам основанию реализовано этой функцией.

Текст кода алгоритма кодирования и раскодирования по произвольному алгоритму:


Функция КодироватьHex(пСтрокаHex, пАлфавит) Экспорт
	Возврат Кодировать(ПолучитьДвоичныеДанныеИзHexСтроки(пСтрокаHex), пАлфавит);
КонецФункции

Функция Кодировать(пДвДанные, пАлфавит) Экспорт
	лБольшоеЧисло = 0;
	лБуферДвДанных = ПолучитьБуферДвоичныхДанныхИзДвоичныхДанных(пДвДанные);
	лЧислоБайт = лБуферДвДанных.Размер;
	лРазмерАлфавита = СтрДлина(пАлфавит); // Алфавит односимвольный
	
	// Получаем большое число
	лСтрока1 = "";

	Для Каждого лТекБайт Из лБуферДвДанных Цикл
		лБольшоеЧисло = лБольшоеЧисло*256 + лТекБайт;
		Если лБольшоеЧисло=0 И лТекБайт=0 Тогда
			лСтрока1 = лСтрока1 + Сред(пАлфавит,1,1); // пишем ноль вначале, если лидирующие байты - нулевые
		КонецЕсли;
	КонецЦикла;
	
	лСтрока2 = "";
	// Разделяем на символы
	лОстаток = лБольшоеЧисло%лРазмерАлфавита;
	лБольшоеЧисло = Цел(лБольшоеЧисло/лРазмерАлфавита);
	Пока лОстаток <> 0 или лБольшоеЧисло > 0 Цикл
		лСтрока2 = Сред(пАлфавит,лОстаток+1,1) + лСтрока2;
		лОстаток = лБольшоеЧисло%лРазмерАлфавита;
		лБольшоеЧисло = Цел(лБольшоеЧисло/лРазмерАлфавита);
	КонецЦикла;
	Возврат лСтрока1+лСтрока2;
КонецФункции

Функция РаскодироватьHex(пСтрока, пАлфавит) Экспорт
	Возврат ПолучитьHexСтрокуИзДвоичныхДанных(Раскодировать(пСтрока, пАлфавит));
конецФункции

Функция Раскодировать(пСтрока, пАлфавит) Экспорт
	лБольшоеЧисло = 0;
	лРазмерАлфавита = СтрДлина(пАлфавит); // Алфавит односимвольный
	лДлинаСтроки = СтрДлина(пСтрока);
	
	лНулевойСимвол = Сред(пАлфавит,1,1); // определяем количество лидирующих "нулей"
	лКолвоНулевых = 0;
	Пока Сред(пСтрока,лКолвоНулевых+1,1) = лНулевойСимвол Цикл
		лКолвоНулевых = лКолвоНулевых + 1;
	КонецЦикла;
	
	// Лидирующие нули добавляют значащие символы в любой системе счисления 1 к 1, а не как a^x = b
	лДлинаБуфера = Окр((лДлинаСтроки-лКолвоНулевых)/ЛогарифмПоОснованию(лРазмерАлфавита,256))+лКолвоНулевых+1; // Создаём буфер с учётом лидирующих "нулей" и небольшим запасом
	лБуферДвДанных = Новый БуферДвоичныхДанных(лДлинаБуфера);
	
	// Получаем большое число
	лСтрока = "";
	нн=0;
	Для н=1 по лДлинаСтроки Цикл
		лТекЧисло = СтрНайти(пАлфавит,Сред(пСтрока,н,1))-1;
		лБольшоеЧисло = лБольшоеЧисло*лРазмерАлфавита + лТекЧисло;
		Если лБольшоеЧисло=0 И лТекЧисло=0 Тогда
			нн=н;
			// лБуферДвДанных.Установить(нн,0); // пишем нулевые байты вначале, если лидирующие символы - нулевые
			// писать нулевые байты смысла нет, они и так там нулевые. просто запоминаем сколько нулевых вначале и всё.
		КонецЕсли;
	КонецЦикла;
	
	// Разделяем на байты
	н = 0;
	лОстаток = лБольшоеЧисло%256;
	лБольшоеЧисло = Цел(лБольшоеЧисло/256);
	Пока лОстаток <> 0 или лБольшоеЧисло > 1 Цикл
		лБуферДвДанных.Установить(лДлинаБуфера-н-1,лОстаток);
		лОстаток = лБольшоеЧисло%256;
		лБольшоеЧисло = Цел(лБольшоеЧисло/256);
		н = н + 1;
	КонецЦикла;
	
	лРеальнаяДлинаБуфера = нн+н;
	
	лДвДанные = ПолучитьДвоичныеДанныеИзБуфераДвоичныхДанных(лБуферДвДанных.Прочитать(лДлинаБуфера-лРеальнаяДлинаБуфера,лРеальнаяДлинаБуфера));
	
	Возврат лДвДанные;
КонецФункции

Функция ЛогарифмПоОснованию(Основание, Показатель)
	Возврат Log10(Показатель)/Log10(Основание);
КонецФункции

Примеры алфавитов:
 

Base-85 ZeroMQ Version (Z85) 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.-:+=^!/*?&<>()[]{}@%$#
Base-64 Bash 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ@_
Base-64 Xxencoding +-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
Base-64 Unix ./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
Base-64 GEDCOM ./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
Base-64 Bcrypt ./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789
Base-58 ripple rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz
Base-58 bitcoin 123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz
Base-58 flickr 123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ
Base-36 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ
Base-32 0123456789ABCDEFGHIJKLMNOPQRSTUV
Vigesimal 0123456789ABCDEFGHJK
Hexadecimal 0123456789ABCDEF
Duodecimal 0123456789AB
Decimal 0123456789
Octal 012345678
Ternary 012
Binary 01


В Обработке реализован представленный код. В форме обработки в поле ввода алфавита есть возможность выбрать из списка различные общепринятые варианты, приведённые в это таблице.

Примеры:

Base58

Алфавит: 123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz
Входящая строка: AABBCCDDEEFF
Кодированная строка: 2U2BSHrY6

Те же самые байты на входе, но по Base85:
5&-d%hf0

Используемая информация и сервисы:

https://www.appdevtools.com/base58-encoder-decoder

http://lenschulwitz.com/base58

https://www.browserling.com/tools/base58-decode

https://ru.qwe.wiki/wiki/Binary-to-text_encoding

https://ru.qwe.wiki/wiki/Base64#Variants_summary_table

Base85 Base64 Base58 Base36 Base32.

См. также

Запрет глобального поиска в конфигурации

Защита ПО и шифрование Платформа 1С v8.3 1С:Бухгалтерия 3.0 Абонемент ($m)

Представляю вам микрорасширение, которое запрещает глобальный поиск по вашей конфигурации.

1 стартмани

09.02.2023    2211    9    aximo    4    

2

Как защитить pdf файл

Защита ПО и шифрование Абонемент ($m)

Для установки защиты pdf документа, полученного в 1С, написано консольное приложение на c#., использующее одну зависимость pdfSharp.dll. В результате работы приложения ограничены операции над документом и записаны метаданные. С помощью аргументов командной строки можно управлять работой приложения.

2 стартмани

30.01.2023    1654    1    olevlasam    3    

3

Универсальный синтаксический анализатор ASN.1 для декодирования .key, .cer, .der, .p7m, .p7s, .crt, .pem

Защита ПО и шифрование Платформа 1С v8.3 Конфигурации 1cv8 Абонемент ($m)

Универсальный синтаксический анализатор ASN.1, который может декодировать любую допустимую структуру ASN.1 DER или BER, независимо от того, закодирована ли она в кодировке Base64 (распознаются необработанные base64, защита PEM и begin-base64) или в шестнадцатеричном кодировании.

1 стартмани

04.12.2022    2964    12    keyn5565`    0    

13

Шифрование строки на основе мастер-пароля в 1С Предприятие 8.3.19

Защита ПО и шифрование Платформа 1С v8.3 Абонемент ($m)

Демонстрация возможностей шифрования строки на основе мастер-пароля в 1С Предприятие 8.3.19. AES без zip файла, RSA, PKDF2. (c использованием библиотеки С# через com).

2 стартмани

31.08.2022    3812    7    vit59    2    

6

Обфускатор байт-кода

Защита ПО и шифрование Платформа 1С v8.3 Конфигурации 1cv8 Россия Абонемент ($m)

Обработка, позволяющая запутывать и шифровать байт-код, поставлять модули без исходных текстов и т.д. Протестировано на платформе 8.3.23.1739.

10 стартмани

16.06.2022    10218    77    ZhokhovM    12    

39

Как уберечь конструкторскую документацию от воровства конкурентами?

Защита ПО и шифрование Платформа 1С v7.7 Платформа 1С v8.3 Абонемент ($m)

Как уберечь конструкторскую документацию от воровства конкурентами? Недавно столкнулся с этой проблемой. Заказчик серьёзно обеспокоен утечкой информации о конструкторских разработках в адрес конкурентов, за счет подкупа исполнителей, занимающихся производством по конструкторской документации, операторов технологического оборудования и обрабатывающих центров по изготовлению деталей и сборочных единиц.

2 стартмани

09.03.2022    5633    3    ge_ni    9    

2

Защита конфигураций, обработок, расширений 1С онлайн, управление версиями

Защита ПО и шифрование Платформа 1С v8.3 Конфигурации 1cv8 Абонемент ($m)

Система построена на веб платформе, все управление происходит на сайте в личном кабинете пользователя.

1 стартмани

27.12.2021    4544    2    idm80    11    

9
Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. mrsmrv 120 14.05.20 21:38 Сейчас в теме
Разгон обработки. Чуть чуть удалось увеличить быстродействие, на тестовых данных объёмом 8 килобайт.
за счёт преобразования алфавита в массив символов. При Кодировании удаётся добиться большего увеличения быстродействия, чем при Раскодировании. При кодировании берётся Сред по номеру символа в строке алфавита, а если брать элемент массива, то это примерно в 4 раза быстрее. А при Раскодировании делается поиск в строке символа, и скорость поиска примерно такая же как и в массиве. Стоит ли делать индексированную ТЗ? проверю, позже.
Время затраченное на создание массива для 58ми символов настолько малО, что единичные вызовы функций происходят дольше. Так что даже на малом объёме данных не имеет смысла Отключать формирования массива.
А сейчас текст функций после оптимизации:

Функция ПолучитьМассивАлфавита(пАлфавит)
	лМассив = Новый Массив;
	Для н=1 По СтрДлина(пАлфавит) Цикл
		лМассив.Добавить(Сред(пАлфавит,н,1));
	КонецЦикла;
	Возврат лМассив;
КонецФункции

Функция Кодировать(пДвДанные, пАлфавит) Экспорт
	лБольшоеЧисло = 0;
	лБуферДвДанных = ПолучитьБуферДвоичныхДанныхИзДвоичныхДанных(пДвДанные);
	лЧислоБайт = лБуферДвДанных.Размер;
	пМассивАлфавита = ПолучитьМассивАлфавита(пАлфавит);
	лРазмерАлфавита = пМассивАлфавита.Количество(); // Алфавит односимвольный
	
	// Получаем большое число
	лСтрока1 = "";

	лНулевойСимвол = пМассивАлфавита[0]; // определяем количество лидирующих "нулей"
	Для Каждого лТекБайт Из лБуферДвДанных Цикл
		лБольшоеЧисло = лБольшоеЧисло*256 + лТекБайт;
		Если лБольшоеЧисло=0 И лТекБайт=0 Тогда
			лСтрока1 = лСтрока1 + лНулевойСимвол; // пишем ноль вначале, если лидирующие байты - нулевые
		КонецЕсли;
	КонецЦикла;
	
	лСтрока2 = "";
	// Разделяем на символы
	лОстаток = лБольшоеЧисло%лРазмерАлфавита;
	лБольшоеЧисло = Цел(лБольшоеЧисло/лРазмерАлфавита);
	Пока лОстаток <> 0 или лБольшоеЧисло > 0 Цикл
		лСтрока2 = пМассивАлфавита[лОстаток] + лСтрока2;
		лОстаток = лБольшоеЧисло%лРазмерАлфавита;
		лБольшоеЧисло = Цел(лБольшоеЧисло/лРазмерАлфавита);
	КонецЦикла;
	Возврат лСтрока1+лСтрока2;
КонецФункции

Функция Раскодировать(пСтрока, пАлфавит) Экспорт
	лБольшоеЧисло = 0;
	пМассивАлфавита = ПолучитьМассивАлфавита(пАлфавит);
	лРазмерАлфавита = пМассивАлфавита.Количество(); // Алфавит односимвольный
	лДлинаСтроки = СтрДлина(пСтрока);
	
	лНулевойСимвол = пМассивАлфавита[0]; // определяем количество лидирующих "нулей"
	лКолвоНулевых = 0;
	Пока Сред(пСтрока,лКолвоНулевых+1,1) = лНулевойСимвол Цикл
		лКолвоНулевых = лКолвоНулевых + 1;
	КонецЦикла;
	
	// Лидирующие нули добавляют значащие символы в любой системе счисления 1 к 1, а не как a^x = b
	лДлинаБуфера = Окр((лДлинаСтроки-лКолвоНулевых)/ЛогарифмПоОснованию(лРазмерАлфавита,256))+лКолвоНулевых+1; // Создаём буфер с учётом лидирующих "нулей" и небольшим запасом
	лБуферДвДанных = Новый БуферДвоичныхДанных(лДлинаБуфера);
	
	// Получаем большое число
	лСтрока = "";
	нн=0;
	Для н=1 по лДлинаСтроки Цикл
		лТекЧисло = пМассивАлфавита.Найти(Сред(пСтрока,н,1));
		лБольшоеЧисло = лБольшоеЧисло*лРазмерАлфавита + лТекЧисло;
		Если лБольшоеЧисло=0 И лТекЧисло=0 Тогда
			нн=н;
			// лБуферДвДанных.Установить(нн,0); // пишем нулевые байты вначале, если лидирующие символы - нулевые
			// писать нулевые байты смысла нет, они и так там нулевые. просто запоминаем сколько нулевых вначале и всё.
		КонецЕсли;
	КонецЦикла;
	
	// Разделяем на байты
	н = 0;
	лОстаток = лБольшоеЧисло%256;
	лБольшоеЧисло = Цел(лБольшоеЧисло/256);
	Пока лОстаток <> 0 или лБольшоеЧисло > 1 Цикл
		лБуферДвДанных.Установить(лДлинаБуфера-н-1,лОстаток);
		лОстаток = лБольшоеЧисло%256;
		лБольшоеЧисло = Цел(лБольшоеЧисло/256);
		н = н + 1;
	КонецЦикла;
	
	лРеальнаяДлинаБуфера = нн+н;
	
	лДвДанные = ПолучитьДвоичныеДанныеИзБуфераДвоичныхДанных(лБуферДвДанных.Прочитать(лДлинаБуфера-лРеальнаяДлинаБуфера,лРеальнаяДлинаБуфера));
	
	Возврат лДвДанные;
КонецФункции

Показать
Прикрепленные файлы:
2. mrsmrv 120 14.05.20 22:00 Сейчас в теме
Применение таблицы значений с индексированной колонкой замедлило.


Функция ПолучитьТЗАлфавита(пАлфавит)
	лТЗ = Новый ТаблицаЗначений;
	лОписаниеТиповСтрока1 = Новый ОписаниеТипов("Строка",,Новый КвалификаторыСтроки(1));
	лОписаниеТиповНомер3 = Новый ОписаниеТипов("Число",Новый КвалификаторыЧисла(3,0,ДопустимыйЗнак.Неотрицательный));
	лТЗ.Колонки.Добавить("Символ",лОписаниеТиповСтрока1);
	лТЗ.Колонки.Добавить("Число",лОписаниеТиповНомер3);
	лТЗ.Индексы.Добавить("Символ");
	Для н=1 По СтрДлина(пАлфавит) Цикл
		л_НовСтр = лТЗ.Добавить();
		л_НовСтр.Символ = Сред(пАлфавит,н,1);
		л_НовСтр.Число = н-1;
	КонецЦикла;
	Возврат лТЗ;
КонецФункции

Показать


место, где было общаение к ТЗ:
		лТекЧисло = лТЗАлфавита.Найти(Сред(пСтрока,н,1),"Символ").Число;


разница даже больше чем при использовании массива, только в обратную сторону, см. Скриншот
Прикрепленные файлы:
3. mrsmrv 120 15.05.20 21:44 Сейчас в теме
(2) Применение соответствия быстрее чем массив.

Функция ПолучитьСоответствиеАлфавита(пАлфавит)
	лСоответствие = Новый Соответствие;
	Для н=1 По СтрДлина(пАлфавит) Цикл
		лСоответствие.Вставить(Сред(пАлфавит,н,1),н-1);
	КонецЦикла;
	Возврат лСоответствие;
КонецФункции

Функция Раскодировать(пСтрока, пАлфавит) Экспорт
	лБольшоеЧисло = 0;
	лСоответствие = ПолучитьСоответствиеАлфавита(пАлфавит);
	лРазмерАлфавита = лСоответствие.Количество(); // Алфавит односимвольный
	лДлинаСтроки = СтрДлина(пСтрока);
	
	лНулевойСимвол = Сред(пАлфавит,1,1); // определяем количество лидирующих "нулей"
	лКолвоНулевых = 0;
	Пока Сред(пСтрока,лКолвоНулевых+1,1) = лНулевойСимвол Цикл
		лКолвоНулевых = лКолвоНулевых + 1;
	КонецЦикла;
	
	// Лидирующие нули добавляют значащие символы в любой системе счисления 1 к 1, а не как a^x = b
	лДлинаБуфера = Окр((лДлинаСтроки-лКолвоНулевых)/ЛогарифмПоОснованию(лРазмерАлфавита,256))+лКолвоНулевых+1; // Создаём буфер с учётом лидирующих "нулей" и небольшим запасом
	лБуферДвДанных = Новый БуферДвоичныхДанных(лДлинаБуфера);
	
	// Получаем большое число
	лСтрока = "";
	нн=0;
	Для н=1 по лДлинаСтроки Цикл
		лТекЧисло = лСоответствие[Сред(пСтрока,н,1)];
		лБольшоеЧисло = лБольшоеЧисло*лРазмерАлфавита + лТекЧисло;
		Если лБольшоеЧисло=0 И лТекЧисло=0 Тогда
			нн=н;
			// лБуферДвДанных.Установить(нн,0); // пишем нулевые байты вначале, если лидирующие символы - нулевые
			// писать нулевые байты смысла нет, они и так там нулевые. просто запоминаем сколько нулевых вначале и всё.
		КонецЕсли;
	КонецЦикла;
	
	// Разделяем на байты
	н = 0;
	лОстаток = лБольшоеЧисло%256;
	лБольшоеЧисло = Цел(лБольшоеЧисло/256);
	Пока лОстаток <> 0 или лБольшоеЧисло > 1 Цикл
		лБуферДвДанных.Установить(лДлинаБуфера-н-1,лОстаток);
		лОстаток = лБольшоеЧисло%256;
		лБольшоеЧисло = Цел(лБольшоеЧисло/256);
		н = н + 1;
	КонецЦикла;
	
	лРеальнаяДлинаБуфера = нн+н;
	
	лДвДанные = ПолучитьДвоичныеДанныеИзБуфераДвоичныхДанных(лБуферДвДанных.Прочитать(лДлинаБуфера-лРеальнаяДлинаБуфера,лРеальнаяДлинаБуфера));
	
	Возврат лДвДанные;
КонецФункции
Показать


5-ти кратный запуск 4-х килобайтной входной строки с массивом 0,110983, с соответствием 0,104367
4. vsesam80 20.05.20 00:02 Сейчас в теме
А где это можно применить?
5. mrsmrv 120 20.05.20 09:01 Сейчас в теме
(4) ну вот например разработка https://infostart.ru/public/1153292/ использовалась в разработке https://infostart.ru/public/1179411/, а вообще, при необходимости передать некоторые двоичные данные в виде текста, с настраиваемыми требованиями к составу символом. Например при передаче двоичных данных в тексте сообщений. Применяя расширенный набор символов существенно сокращается длина строки. А например base58 применяется для кодирования с использованием только удобочитаемых символов, перепутать которые с аналогичными по начертанию проблематично. Таким способом записываются адреса в популярных блокчейнах.
Оставьте свое сообщение