Существует немало информации на тему получения MD5 хеша строки или файла. В этой статье я попробую рассмотреть самые популярные способы решения подобной задачи.
Средства платформы
В версии платформы 8.3 наконец-то был реализован штатный механизм хеширования данных, который позволяет хешировать строки и файлы при помощи алгоритмов MD5, SHA1, SHA256 и CRC32.
Делается это просто:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | &НаКлиенте Процедура Хеширование(Команда) Сообщить(MD5ХешСтрока(ТестСтрока)); Сообщить(MD5ХешФайл(ИмяФайла)); КонецПроцедуры &НаСервере Функция MD5ХешСтрока(тСтрока) Хеш = Новый ХешированиеДанных(ХешФункция.MD5); Хеш.Добавить(тСтрока); Возврат Хеш.ХешСумма; КонецФункции &НаСервере Функция MD5ХешФайл(тСтрока) Хеш = Новый ХешированиеДанных(ХешФункция.MD5); Хеш.ДобавитьФайл(тСтрока); Возврат Хеш.ХешСумма; КонецФункции |
Если же использовать этот штатный механизм Вы по каким-либо причинам не можете, то ниже Вы найдете еще несколько способов, один из которых наверняка Вам подойдет.
Объект CAPICOM.HashedData
Код для строки:
1 2 3 4 5 6 7 8 9 | &НаКлиенте Процедура MD5(СтрокаДляХеширования) Crypt = Новый COMОбъект("CAPICOM.HashedData"); Crypt.Algorithm = 3; Crypt.Hash(СтрокаДляХеширования); Сообщить(Crypt.Value); КонецПроцедуры |
Код для файла:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | &НаКлиенте Процедура ПервыйСпособ(Команда) Crypt = Новый COMОбъект("CAPICOM.HashedData"); Crypt.Algorithm = 3; Stream = Новый COMОбъект("ADODB.Stream"); Stream.Type = 1; Stream.Open(); Stream.LoadFromFile(ИмяФайла); Пока НЕ Stream.EOS Цикл Crypt.Hash(Stream.Read()); КонецЦикла; Сообщить(Crypt.Value); КонецПроцедуры |
К плюсам данного способа следует отнести простоту, элегантность и универсальность — свойство Algorithm может принимать следующие значения:
- 0 — SHA1;
- 1 — MD2;
- 2 — MD4;
- 3 — MD5;
- 4 — SHA-256;
- 5 — SHA-384;
- 6 — SHA-512.
Но у этого способа есть один очень серьезный минус — библиотека CAPICOM.HashedData присутствует только в Windows не старше Vista/Server 2008.
Объект MD5CryptoServiceProvider
В Windows 7 и последующих версиях Windows хеширование осуществляется при помощи платформы .NET, следовательно для следующего метода необходима эта платформа. Кроме самой платформы, потребуется функция преобразующая десятичные значения в шестнадцатеричные, например такая:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | &НаКлиенте Функция DecToHex(Знач Число) тЧисло = Число; тБаза = 16; Пока тЧисло <> 0 Цикл тПоз =тЧисло % тБаза; Результат = Сред("0123456789abcdef", тПоз + 1, 1) + Результат; тЧисло = Цел(тЧисло / тБаза); КонецЦикла; Если Число < тБаза Тогда Результат = "0" + Результат; КонецЕсли; Возврат Результат; КонецФункции |
Код для получения хеша строки выглядит так:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | &НаКлиенте Функция MD5Строка(тСтрока) Crypt = Новый COMОбъект("System.Security.Cryptography.MD5CryptoServiceProvider"); Text = Новый COMОбъект("System.Text.UTF8Encoding"); HashArray = Crypt.ComputeHash_2(Text.GetBytes_4(тСтрока)).Выгрузить(); Hash = ""; Для Каждого Число Из HashArray Цикл Hash = Hash + DecToHex(Число); КонецЦикла; Возврат Hash; КонецФункции |
Для получения хеша файла — так:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | &НаКлиенте Функция MD5Файл(тИмяФайла) Crypt = Новый COMОбъект("System.Security.Cryptography.SHA1Managed"); Stream = Новый COMОбъект("ADODB.Stream"); Stream.Open(); Stream.Type = 1; Stream.LoadFromFile(тИмяФайла); HashArray = Crypt.ComputeHash_2(Stream.Read()); Hash = ""; Для Каждого Число Из HashArray Цикл Hash = Hash + DecToHex(Число); КонецЦикла; Возврат Hash; КонецФункции |
В обоих примерах MD5CryptoServiceProvider можно заменить на SHA1Managed, SHA256Managed, SHA384Managed или SHA512Managed изменив тем самым метод хеширования.
Объект MSScriptControl.ScriptControl
Ну и наконец, рассмотрим последний, в моем списке, способ основан на реализации MD5 в JavaScript, минусом этого способа являются его недоступность на 64-х битном сервере 1С, а также немалый объем кода. Сам код этого способа я приводить не буду, по уже упомянутой причине объема кода, функция доступна в текстовом файле.
На этом все, надеюсь эта статья Вам помогла.
Полезная статья, спасибо.
На основе это статьи я написал универсальную функция MD5.
Функция УниверсалнаяMD5СуммаСтроки(СтрокаДляХеширования)
Результат = «»;
СисИнфо = Новый СистемнаяИнформация;
Версия1С = Число(Лев(СисИнфо.ВерсияПриложения,3));
ВерсияWindows = Число(Лев(СтрЗаменить(СтрЗаменить(СисИнфо.ВерсияОС, «version», «»),» «,»»),3));
Windows7 = 6.1; // Список версий Windows — https://msdn.microsoft.com/en-us/library/windows/desktop/ms724832%28v=vs.85%29.aspx
Если Версия1С >= 8.3 Тогда
Хеш = Новый ХешированиеДанных(ХешФункция.MD5);
Хеш.Добавить(СтрокаДляХеширования);
Результат = Хеш.ХешСумма;
Иначе
Если ВерсияWindows < Windows7 Тогда
Crypt = Новый COMОбъект("CAPICOM.HashedData");
Crypt.Algorithm = 3;
Crypt.Hash(СтрокаДляХеширования);
Результат = Crypt.Value;
Иначе
Crypt = Новый COMОбъект("System.Security.Cryptography.MD5CryptoServiceProvider");
Text = Новый COMОбъект("System.Text.UTF8Encoding");
HashArray = Crypt.ComputeHash_2(Text.GetBytes_4(СтрокаДляХеширования)).Выгрузить();
Для Каждого Число Из HashArray Цикл
Результат = Результат + DecToHex(Число);
КонецЦикла;
КонецЕсли;
КонецЕсли;
Результат = НРег(СтрЗаменить(Результат, " ",""));
Возврат Результат;
КонецФункции // УниверсалнаяMD5СуммаСтроки
Не будет работать на Linux серверах
И у вас не указано определение функции DecToHex()
Функция DecToHex(Знач _Число)
База = 16;
Результат = «»;
Пока _Число 0 Цикл
Поз =_Число % База;
Результат = Сред(«0123456789ABCDEF», Поз + 1, 1) + Результат;
_Число = Цел(_Число / База);
КонецЦикла;
Возврат Результат;
КонецФункции // DecToHex()
Хорошая статья, спасибо автору.
Есть небольшая поправка к функции DecToHex(), выдает ошибку для байта 0
2715b129922241c6d721eba6571f00a9 — правильно
2715b129922241c6d721eba6571f0a9 — не правильно, байт == 0х00 —> «0»
Функция DecToHex(Знач тЧисло)
НачальноеЧисло = тЧисло;
тБаза = 16;
Если тЧисло = 0 Тогда
Возврат «00»;
Иначе
Пока тЧисло 0 Цикл
тПоз = тЧисло % тБаза;
Результат = Сред(«0123456789abcdef», тПоз + 1, 1) + Результат;
тЧисло = Цел(тЧисло / тБаза);
КонецЦикла;
Если НачальноеЧисло < тБаза Тогда
Результат = "0" + Результат;
КонецЕсли;
Возврат Результат;
КонецЕсли;
КонецФункции
При хэшировании с помощью платформы .Net (MD5CryptoServiceProvider) Выходит ошибка
{ОбщийМодуль.пп_Сервер.Модуль(1535)}: Значение не является значением объектного типа (GetBytes_4)
HashArray = Crypt.ComputeHash_2(UTF8.GetBytes_4(КодируемаяСтрока));
Подскажите — чего не хватает?