В расширении представлены алгоритмы:
- Кодирования / декодирования строки в base58.
- Кодирование строк utf8 в массив байт и декодирование массива байт в строку uft8
Данные алгоритмы перенесены с JS. За основу взята библиотека ts-lib-crypto. Внешние компоненты в разработки не использовались. Для использования алгоритмов необходима платформа версии не ниже 8.3.11
Разработка распространяется под лицензией MIT.
Исходный код всех модулей представлен ниже:
base58_encode
// Функция — Base58 encode
//
// Параметры:
// Буфер — Массив — Массив байт, Результат функции base58 decode
//
// Возвращаемое значение:
// Строка — Результат кодирование байт в строку
//
Функция base58_encode(Знач Буфер) Экспорт
Если ТипЗнч(Буфер) <> ТипЗнч(Новый Массив) Тогда
Возврат "";
КонецЕсли;
Если Буфер.Количество() = 0 Тогда
Возврат "";
КонецЕсли;
Числа = Новый Массив;
Числа.Добавить(0);
сч = 0;
Пока сч < Буфер.Количество() Цикл
счч = 0;
Пока счч < Числа.Количество() Цикл
Числа[счч] = ПобитовыйСдвигВлево(Числа[счч], 8);
счч = счч + 1;
КонецЦикла;
Числа[0] = Числа[0] + Буфер[сч];
carry = 0;
к = 0;
Пока к < Числа.Количество() Цикл
Числа[к] = Числа[к] + carry;
Если Числа[к] % 58 = 0 Тогда
carry = ПобитовоеИли(Числа[к] / 58, 0);
Иначе
carry = Числа[к] / 58;
carry = Число(Лев(carry, СтрНайти(carry, ",") — 1));
Если ЗначениеЗаполнено(carry) тогда
carry = Число(carry);
Иначе
carry = 0;
КонецЕсли;
КонецЕсли;
Числа[к] = Числа[к] % 58;
к = к + 1;
КонецЦикла;
Пока carry <> 0 Цикл
Числа.Добавить(carry % 58);
Если carry % 58 = 0 Тогда
carry = ПобитовоеИли((carry / 58), 0);
Иначе
carry = carry / 58;
carry = Число(Лев(carry, СтрНайти(carry, ",") — 1));
Если ЗначениеЗаполнено(carry) тогда
carry = Число(carry);
Иначе
carry = 0;
КонецЕсли;
КонецЕсли;
КонецЦикла;
сч = сч + 1;
КонецЦикла;
сч = 0;
Пока (Буфер[сч] = "0" И сч < Буфер.Количество() — 1) Цикл
Числа.Добавить(0);
сч = сч + 1;
КонецЦикла;
ALPHABET = Crypt_ОбщегоНазначенияКлиентСевер.ПолучитьСтруктуруALPHABET();
Результат = "";
Для Каждого Индекс из Crypt_ОбщегоНазначенияКлиентСевер.РазвернутьМассив(Числа) Цикл
Результат = Результат + ALPHABET.Массив[Индекс];
КонецЦикла;
Возврат Результат;
КонецФункции
base58_decode
// Функция — Base58 decode
//
// Параметры:
// тСтр — Строка — Строка
//
// Возвращаемое значение:
// Массив — данные в Base58
//
Функция base58_decode(Знач тСтр) Экспорт
ALPHABET = Crypt_ОбщегоНазначенияКлиентСевер.ПолучитьСтруктуруALPHABET();
Если Не ЗначениеЗаполнено(тСтр) Тогда
Возврат Новый Массив;
КонецЕсли;
Байты = Новый Массив;
Байты.Добавить(0);
Для сч = 1 По СтрДлина(тСтр) Цикл
с = Сред(тСтр, сч, 1);
Если ALPHABET.Массив.Найти(с) = Неопределено Тогда
ВызватьИсключение "There is no character " + с + " in the Base58 sequence!";
КонецЕсли;
счч = 0;
Пока счч < Байты.Количество() Цикл
Байты[счч] = Байты[счч] * 58;
счч = счч + 1;
КонецЦикла;
Байты[0] = Байты[0] + (ALPHABET.Массив.Найти(с));
carry = 0;
счч = 0;
Пока счч < Байты.Количество() Цикл
Байты[счч] = Байты[счч] + carry;
carry = ПобитовыйСдвигВправо(Байты[счч], 8);
Байты[счч] = ПобитовоеИ(Байты[счч], 255);
счч = счч + 1;
КонецЦикла;
Пока carry <> 0 Цикл
Байты.Добавить(ПобитовоеИ(carry, 255));
carry = ПобитовыйСдвигВправо(carry, 8);
КонецЦикла;
КонецЦикла;
сч = 1;
Пока (Сред(тСтр, сч, 1) = "1" и сч < Байты.Количество()) Цикл
Байты.Добавить(0);
КонецЦикла;
Возврат Crypt_ОбщегоНазначенияКлиентСевер.РазвернутьМассив(Байты);
КонецФункции
Crypt_ОбщегоНазначенияКлиентСевер
///////////////////////////////////////////////////////////////////////////////////
//Модуль — Общего назначения Клиент Сервер
///////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////
#Область ОбщиеПроцедурыФункции
// Функция — Получить структуру ALPHABET
//
// Возвращаемое значение:
// Структура — Ключи струкруры: Строка, Массив
//
Функция ПолучитьСтруктуруALPHABET() Экспорт
Результат = Новый Структура;
Результат.Вставить("Строка",
"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz");
ALPHABET_СРазделителями = "1,2,3,4,5,6,7,8,9,A,B,C,D,E,F,G,H,J,K,"+
"L,M,N,P,Q,R,S,T,U,V,W,X,Y,Z,a,b,c,d,e,f,g,h,i,j,k,m,n,o,p,q,r,s,t,u,v,w,x,y,z";
Результат.Вставить("Массив", РазложитьСтрокуВМассив(ALPHABET_СРазделителями));
Возврат Результат;
КонецФункции
#КонецОбласти
///////////////////////////////////////////////////////////////////////////////////
#Область Массивы
// Функция — Разложить строку в массив
//
// Параметры:
// Стр — Строка — Строка с разделителями
// Разделитель — Разделитель — Разделитель подстрок
//
// Возвращаемое значение:
// Массив — Массив подстрок
//
Функция РазложитьСтрокуВМассив(Знач Стр, Разделитель = ",") Экспорт
Результат = Новый Массив;
Строки = СтрЗаменить(Стр, Разделитель, Символы.ПС);
Для Индекс = 1 По СтрЧислоСтрок(Строки) Цикл
Результат.Добавить(СтрПолучитьСтроку(Строки, Индекс));
КонецЦикла;
Возврат Результат;
КонецФункции
// Функция — Разложить массив в строку
//
// Параметры:
// Массив — Массив — Элементы которого разложим в строку
// Разделитель — Строка — Разделитель элементов массива
//
// Возвращаемое значение:
// Строка — Строка из элементов массива, с раздилителями
//
Функция РазложитьМассивВСтроку(Знач Массив, Разделитель = ",") Экспорт
СтрокаРезультат = "";
Для Каждого ЭлементМассива Из Массив цикл
СтрокаРезультат = СтрокаРезультат + СокрЛП(Строка(ЭлементМассива)) + Разделитель;
КонецЦикла;
СтрокаРезультат = Лев(СтрокаРезультат, СтрДлина(СтрокаРезультат) — 1);
Возврат СтрокаРезультат;
КонецФункции
// Функция — Развернуть массив
//
// Параметры:
// пМассив — Массив — Массив который необходимо развернуть
//
// Возвращаемое значение:
// Массив — Массив с обратной последовательностью элементов
//
Функция РазвернутьМассив(Знач пМассив) Экспорт
рМассив = Новый Массив;
сч = пМассив.Количество() — 1;
Пока сч > -1 Цикл
рМассив.Добавить(пМассив[сч]);
сч = сч — 1;
КонецЦикла;
Возврат рМассив;
КонецФункции
#КонецОбласти
///////////////////////////////////////////////////////////////////////////////////
СтрокаВUtf8МассивБайт
// Функция — Строка в utf8 массив байт
//
// Параметры:
// тСтрока — Строка — Строка в кодировки uft8
//
// Возвращаемое значение:
// Массив — Массив байт построенный по строке uft8
//
Функция СтрокаВUtf8МассивБайт(Знач тСтрока) Экспорт
МассивUtf8 = Новый Массив;
сч = 1;
Пока сч <= СтрДлина(тСтрока) Цикл
СимвольныйКод = КодСимвола(тСтрока, сч);
Если СимвольныйКод < 128 Тогда
МассивUtf8.Добавить(СимвольныйКод);
ИначеЕсли СимвольныйКод < 2048 Тогда
МассивUtf8.Добавить(ПобитовоеИли(192, ПобитовыйСдвигВправо(СимвольныйКод, 6)));
МассивUtf8.Добавить(ПобитовоеИли(128, ПобитовоеИ(63, СимвольныйКод)));
ИначеЕсли СимвольныйКод < 55296 ИЛИ СимвольныйКод > 57344 Тогда
МассивUtf8.Добавить(ПобитовоеИли(224, ПобитовыйСдвигВправо(СимвольныйКод, 12)));
МассивUtf8.Добавить(ПобитовоеИли(128,
ПобитовоеИ(ПобитовыйСдвигВправо(СимвольныйКод, 6), 63)));
МассивUtf8.Добавить(ПобитовоеИ(128, ПобитовоеИ(СимвольныйКод, 63)));
Иначе
СимвольныйКод = 65536 + ПобитовоеИли(
ПобитовыйСдвигВлево(ПобитовоеИ(СимвольныйКод, 1023), 10),
ПобитовоеИ(КодСимвола(тСтрока, сч + 1), 1023));
МассивUtf8.Добавить(ПобитовоеИли(240, ПобитовыйСдвигВправо(СимвольныйКод, 18)));
МассивUtf8.Добавить(ПобитовоеИли(128,
ПобитовоеИ(ПобитовыйСдвигВправо(СимвольныйКод, 12),63)));
МассивUtf8.Добавить(ПобитовоеИли(128,
ПобитовоеИ(ПобитовыйСдвигВправо(СимвольныйКод, 6), 63)));
МассивUtf8.Добавить(ПобитовоеИли(128, ПобитовоеИ(СимвольныйКод, 63)));
КонецЕсли;
сч = сч + 1;
КонецЦикла;
Возврат МассивUtf8;
КонецФункции
МассивБайтВUtf8Строку
// Функция — Массив байт в utf8 строку
//
// Параметры:
// мБайт — Массив — Массив байт строки формата utf8
//
// Возвращаемое значение:
// Строка — строка раскодированная по массиву байт
//
Функция МассивБайтВUtf8Строку(Знач мБайт) Экспорт
Байт = Неопределено;
Код = Неопределено;
Результат = "";
сч = 0;
Пока сч < мБайт.Количество() Цикл
Байт = мБайт[сч];
Если Байт <= 127 Тогда
Код = Байт;
ИначеЕсли Байт <= 223 Тогда
сч = сч + 1;
Код = ПобитовоеИли(ПобитовыйСдвигВлево(ПобитовоеИ(Байт, 31), 6), ПобитовоеИ(мБайт[сч], 63));
ИначеЕсли Байт <= 239 Тогда
Код = ПобитовоеИли(ПобитовоеИли(ПобитовыйСдвигВлево(ПобитовоеИ(Байт, 15), 12),
ПобитовыйСдвигВлево(ПобитовоеИ(мБайт[сч + 1], 63), 6)),
ПобитовоеИ(мБайт[сч + 2], 63));
сч = сч + 2;
Иначе
Код = 63;
сч = сч + 3;
КонецЕсли;
сч = сч + 1;
Результат = Результат + Символ(Код);
КонецЦикла;
Возврат Результат;
КонецФункции
Разработка не предусматривает интерфейса и состоит только из общих модулей.
Related Posts
- Получение логина и пароля техподдержки 1С из базы
- Класс для вывода отчета в Excel
- Счет-фактура для УПП
- Библиотека классов для создания внешней компоненты 1С на C#
- Акт об оказании услуг (со скидками) — внешняя печатная форма для Управление торговлей 11.1.10.86
- Прайс-лист с артикулом в отдельной колонке
в 1с8 вычислительные операции долгие. замените их подстановкой из массива(соответствия). и не по байту , а по 2-3