MD5 Hash файла

Получение md5 хэша для файла

Бывают случаи, когда необходимо получать какой-либо хэш для файла. В состав операционной системы входит библиотека криптографии capicom.dll, используя которую можно получить интересующий нас хэш. Привожу код для 7.7, его без труда можно перевести на 8.х

 

 

Функция  МД5(файл)
   
ScrCtrl = СоздатьОбъект(«MSScriptControl.ScriptControl»);
   
ScrCtrl.Language = «vbscript»;
   
ScrCtrl.AddCode(«
    |Function Hash()
    |Dim crypt: Set crypt = CreateObject(«»CAPICOM.HashedData»»)
    |crypt.Algorithm = 3
    |Dim stream: Set stream = CreateObject(«»ADODB.Stream»»)
    |stream.Type = 1 ‘ adTypeBinary
    |stream.Open
    |stream.LoadFromFile(«»»
+файл+«»»)
    |Do Until stream.EOS : crypt.Hash stream.Read() : Loop
    |Hash = crypt.Value
    |End Function
    |»
);
   
рез = ScrCtrl.Run(«Hash»);
    Возврат
рез;
КонецФункции

Кроме того, указав в этой функции другой алгоритм можно получить хэш SHA1, MD2, MD4, SHA-256, SHA-384 и SHA-512.

Подробнее http://msdn.microsoft.com/en-us/library/aa382443(VS.85).aspx

UPD: код для 1с8, любезно предоставленный в комментариях Mikelana

Функция  МД5(файл)

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;

КонецФункции

23 Comments

  1. Арчибальд

    Кто бы научил еще контрольную сумму считать… 😐

    Reply
  2. d0dger

    Когда-то мучал CRC32 по таблице, добился только того что считает, но не всегда корректно — видимо не работает для бинарных файлов, подниму архив, вдруг удастся побороть…

    Reply
  3. cool.vlad4

    http://www.forum.script-coding.com/viewtopic.php?id=5565

    DynamicWrapper выходных чисел не понимает, лучше используй DynamicWrapperX

    Код:

    Set Wrap = CreateObject(«DynamicWrapperX»)

    Wrap.Register «ImageHlp.DLL», «MapFileAndCheckSum», «i=sUU», «r=u»

    sHeader = 0

    sCalcd = 0

    ress = Wrap.MapFileAndCheckSum(«c:
    eadme.txt», sHeader, sCalcd)

    WScript.Echo sCalcd & » » & sHeader & » » & ress

    Reply
  4. Арчибальд

    (3) А что все про CRC32? Мне CRC8 надо.

    Reply
  5. d0dger

    cool.vlad4,спасибо, попробовал, думал crc32, оказалось нет. Вдруг кому пригодиться код:

    Функция ПолучитьCheckSum(Путь)
    ScrptCtrl = СоздатьОбъект(«MSScriptControl.ScriptControl»);
    ScrptCtrl.Language = «VBScript»;
    ScrptCtrl.AddCode(«Function CheckSum
    |Set Wrap = CreateObject(«»DynamicWrapperX»»)
    |Wrap.Register «»ImageHlp.DLL»», «»MapFileAndCheckSum»», «»i=sUU»», «»r=u»»
    |sHeader = 0
    |sCalcd = 0
    |ress = Wrap.MapFileAndCheckSum(«»» + Путь + «»», sHeader, sCalcd)
    |CheckSum = sCalcd
    |End Function»);
    рез = ScrptCtrl.Run(«CheckSum»);
    Возврат рез;
    КонецФункции

    Показать

    Reply
  6. cool.vlad4

    (5) Не за, что , я наверное ссылкой вас с толку сбил, просто код взят из той ссылки (я уже не помню правда где)

    библиотека msdn http://msdn.microsoft.com/en-us/library/ms680355(VS.85).aspx всегда поможет

    ЗЫ враппер кстати в 1С тоже можно использовать, некогда просто было код на 1с-ке писать

    Reply
  7. d0dger

    (6) можно, но там проблемы с передачей параметров sHeader и sCalcd возникли. По крайней мере у меня…

    Reply
  8. pupkinSana

    уж проще формекс: сервис.ПолучитьХэшМД5(<?>,)

    Reply
  9. cool.vlad4

    (8) Где ты видел формекс под 8.1 и уж тем более под 8.2

    Reply
  10. Mikelana

    Вот для 8.* без ScriptControl

    Функция  МД5(файл)
    
    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;
    
    КонецФункции

    Показать

    Reply
  11. yoyoman

    Кириллицу как-то не корректно хеширует 🙁

    А как можно подобным способом строку захешировать в md5?

    Reply
  12. d0dger

    (12) yoyoman, а какая кодировка кириллицы?

    Можно написать

    stream.charset = «windows-1251»;

    или

    stream.charset = «UTF-8»

    А чтобы закодировать строку можно попробовать нечто такое:

    …
    stream.Open();
    stream.WriteText(Строка);
    …
    
    Reply
  13. yoyoman

    (13) я себе такую функцию сделал для получения хеша строки (не файла):

    Функция Hash(Значение,Алгоритм)
    ВременныйФайл = ПолучитьИмяВременногоФайла(«txt»);
    Файл = Новый ТекстовыйДокумент;
    Файл.УстановитьТекст(Значение);
    Файл.Записать(ВременныйФайл,»Windows-1251″);
    ВК_Capicom = Новый COMОбъект(«CAPICOM.HashedData»);
    Если Алгоритм=»sha1″ тогда
    ВК_Capicom.Algorithm = 0;
    ИначеЕсли Алгоритм = «md5» тогда
    ВК_Capicom.Algorithm = 3;
    КонецЕсли;
    ВК_ADODB = Новый COMОбъект(«ADODB.Stream»);
    ВК_ADODB.Type = 1;
    ВК_ADODB.Open();
    ВК_ADODB.LoadFromFile(ВременныйФайл);
    Пока НЕ ВК_ADODB.EOS Цикл
    ВК_Capicom.Hash(ВК_ADODB.Read());
    КонецЦикла;
    Попытка
    УдалитьФайлы(ВременныйФайл);
    Исключение
    КонецПопытки;
    Возврат НРег(ВК_Capicom.Value);
    КонецФункции
    

    Показать

    Функция работает нормально если ее кормить латиницей 🙂

    Почему сделал через временный файл — потому что я дурак не понял как напрямую строку передавать 🙂

    Указанная ниже конструкция возвращает неверный хеш для «asd». Как я понял это связано с кодировками, сообразить как все сделать нормально — я не смог 🙂

    ВК_Capicom = Новый COMОбъект(«CAPICOM.HashedData»);
    ВК_Capicom.Algorithm = 3;
    ВК_Capicom.Hash(«asd»);
    Возврат ВК_Capicom.Value;
    
    Reply
  14. yoyoman
    stream.charset = «Windows-1251»

    Ругается

    Произошла исключительная ситуация (ADODB.Stream): Операция не допускается в данном контексте.
    Reply
  15. d0dger

    ругается потому что тип файла — бинарный (stream.Type = 1;), для него нет кодировок, просто последовательность байтов.

    Можно попробовать

    stream.Type = 2;
    stream.charset = «windows-1251»;
    

    а вообще я с кириллицей не воевал, это тема отдельных экспериментов )

    Reply
  16. irbis_triffle
    Reply
  17. yandextesting

    в 8.3 реализовано на уровне платформы

    …
    Хеш = ПолучитьMD5_Сервер(ТекстДляХеша);
    …
    
    Функция ПолучитьMD5_Сервер(Текст)
    
    ОбъектХеш = Новый ХешированиеДанных(ХешФункция.MD5);
    ОбъектХеш.Добавить(Текст);
    Возврат ОбъектХеш.ХешСумма;
    
    КонецФункции // ПолучитьMD5_Сервер

    Показать

    Reply
  18. d0dger

    Интересно, а есть ограничения на размер строки в 8.3?

    Reply
  19. NastyMosk

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

    Reply
  20. Angeros

    Что делать тем кто хочет хешировать картинки и выдается ошибка

    Ошибка при вызове конструктора (COMОбъект)

    crypt = Новый COMОбъект(«CAPICOM.HashedData»);

    по причине:

    Недопустимая строка с указанием класса

    ?

    Reply
  21. d0dger
  22. NAKIS

    Спасибо, если самому не получится реализовать, то качну)))

    Но лень, это такая злая штука…))

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *