1. Наш канал codeby в telegram. Пишем об информационной безопасности, методах защиты информации, о программировании. Не пропускай новости с кодебай, будь в тренде ! Подробнее ...

    Скрыть объявление

Вычисление md5-хэша файла

Тема в разделе "Lotus + Java + LS2J", создана пользователем VladSh, 17 янв 2012.

  1. VladSh

    VladSh начинающий
    Lotus team

    Репутация:
    0
    Регистрация:
    11 дек 2009
    Сообщения:
    1.248
    Симпатии:
    2
    Привет всем!

    Надо понять, изменился файл или нет. Анализ даты и версии не подходит. нужен только хэш.
    Хотелось бы что-то родное, на LS, т.к. скорость здесь критична.
    HashPassword + VerifyPassword не подходят, т.к. они работают для слишком уж маленьких файлов.. мой файл в 55kb уже не проверяется - всегда возвращается True.
    Или придётся всё-таки крутить MD5 и LS2J?

    Поделитесь соображениями, плз! От кода тоже не стану отказываться :lovecodeby:
     
  2. ToxaRat

    ToxaRat Чёрный маг
    Lotus team

    Репутация:
    0
    Регистрация:
    6 ноя 2007
    Сообщения:
    3.195
    Симпатии:
    24
    бери виндусовый хешер, он кажется даже в ЕЦП использовался
     
  3. nvyush

    nvyush Well-Known Member
    Lotus team

    Репутация:
    0
    Регистрация:
    22 апр 2009
    Сообщения:
    2.317
    Симпатии:
    0
  4. VladSh

    VladSh начинающий
    Lotus team

    Репутация:
    0
    Регистрация:
    11 дек 2009
    Сообщения:
    1.248
    Симпатии:
    2
    Ясно.. - куча кода.. тогда лучше действительно Java.

    Странности..
    1.
    stream.Open(sFilePathFull, "Binary")
    берёт всего лишь 172 символа из моего бинарника

    stream.Open(sFilePathFull, "ASCII")
    берёт всё содержимое файла

    2. При получении строки из файла используя ASCII при добавлении в файл в конец одного пробела размер изменяется, а хэш (код отсюда) нет. Есть подозрение, что хоть строка и вся, но для обсчёта берётся только какой-то кусок.

    Одни, блин, сюрпризы...
     
  5. lmike

    lmike нет, пердело совершенство
    Lotus team

    Репутация:
    3
    Регистрация:
    27 авг 2008
    Сообщения:
    6.406
    Симпатии:
    346
    ну менябы смутило вот это :lovecodeby: - m.update(str.getBytes("utf-8"));
     
  6. VladSh

    VladSh начинающий
    Lotus team

    Репутация:
    0
    Регистрация:
    11 дек 2009
    Сообщения:
    1.248
    Симпатии:
    2
    lmike
    Тоже как-то смутило, когда код копипастил, но потом забыл :lovecodeby:
    Что посоветуешь туда втулить? ASCII не помогло, - возвращает тот же хэш.
     
  7. lmike

    lmike нет, пердело совершенство
    Lotus team

    Репутация:
    3
    Регистрация:
    27 авг 2008
    Сообщения:
    6.406
    Симпатии:
    346
    файл произвольный?
    есть такая ссылка http://www.twmacinta.com/myjava/fast_md5.php
    там могет нативный хэшер дергаться (если есть), ну и бенчи
     
  8. VladSh

    VladSh начинающий
    Lotus team

    Репутация:
    0
    Регистрация:
    11 дек 2009
    Сообщения:
    1.248
    Симпатии:
    2
    Файл в данный момент обычная dll, но в принципе хотелось бы вычислять хэш любого файла.
     
  9. lmike

    lmike нет, пердело совершенство
    Lotus team

    Репутация:
    3
    Регистрация:
    27 авг 2008
    Сообщения:
    6.406
    Симпатии:
    346
    с кодировкой вопрос открытый, бинарный следует использовать для бинарных файлов, а вот файлы в кодировке - это совсем другой момент...
    когда открываем файл стримом (например в ЮТФ) - оно ещё не понимабельно нотуснёю (если пытаться вывести как стринг)
    и надо конвертить, непример, через майм
    др. словами - луче открывать файл в джава, а не передавать стринг открытый в LS из ёваного стрима

    Добавлено: вот экзампел для файла http://www.javalobby.org/java/forums/t84420.html
     
  10. VladSh

    VladSh начинающий
    Lotus team

    Репутация:
    0
    Регистрация:
    11 дек 2009
    Сообщения:
    1.248
    Симпатии:
    2
    Спасибо, буду разбираться!
    В этом примере не увидел, где задаётся кодировка.. И хотелось бы, чтобы код автоматом определял, что оно, бинарник или нет; такое возможно? Или это оно и есть?
     
  11. lmike

    lmike нет, пердело совершенство
    Lotus team

    Репутация:
    3
    Регистрация:
    27 авг 2008
    Сообщения:
    6.406
    Симпатии:
    346
    is.read(buffer) читает байты - там кодировка не нужна
     
  12. turumbay

    Репутация:
    0
    Регистрация:
    13 мар 2009
    Сообщения:
    625
    Симпатии:
    2
    <div class="sp-wrap"><div class="sp-head-wrap"><div class="sp-head folded clickable">Java LIbrary: MD5Digest</div></div><div class="sp-body"><div class="sp-content">
    Код:
    package ru.turumbay.forum;
    
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.security.DigestInputStream;
    import java.security.MessageDigest;
    import java.security.NoSuchAlgorithmException;
    
    public class MD5Digest {
    public static String digest(String plaintext){
    MessageDigest md5 = getMessageDigest();
    md5.update(plaintext.getBytes());
    return toHexString(md5.digest());
    }
    
    private static MessageDigest getMessageDigest(){
    try {
    return MessageDigest.getInstance("MD5");
    } catch (NoSuchAlgorithmException e) {
    throw new RuntimeException(e);
    }
    }
    
    public static String digest(InputStream is) throws IOException {
    MessageDigest md5 = getMessageDigest();
    DigestInputStream din = new DigestInputStream(is, md5);
    byte[] buffer = new byte[8192];
    while ((din.read(buffer)) != -1);
    din.close();
    return toHexString(md5.digest());
    }	
    
    public static String digest(File file) throws IOException{
    InputStream is = new FileInputStream(file);
    try{
    return digest(is);
    }finally{
    is.close();
    }
    }
    
    public static String toHexString(byte bytes[]){
    StringBuffer hexString = new StringBuffer();
    for (int i=0;i<bytes.length;i++) {
    hexString.append(Integer.toHexString((bytes[i] >>> 4) & 0x0F));
    hexString.append(Integer.toHexString(0x0F & bytes[i]));
    }
    return hexString.toString();
    }
    }
    <div class="sp-wrap"><div class="sp-head-wrap"><div class="sp-head folded clickable">Обертка. LS Library: MD5Digest.LS</div></div><div class="sp-body"><div class="sp-content">
    Код:
    Option Public
    Option Declare
    
    Uselsx "*javacon"
    Use "MD5Digest"
    
    Class MD5Digest
    Public Function getFileHash(fileName As String)
    getFileHash = getMD5DigestClass().digest( getFileObj(fileName) )
    End Function
    
    Public Function getStringHash( st As String )
    getStringHash = getMD5DigestClass().digest( st )
    End Function
    
    Private Function getMD5DigestClass As JavaClass
    Dim jSession As New JAVASESSION
    Set getMD5DigestClass = jSession.GetClass("ru/turumbay/forum/MD5Digest")
    End Function
    
    Private Function getFileObj(fileName As String) As JavaObject
    Dim jSession As New JAVASESSION
    Dim fileClass As JAVACLASS
    Set fileClass = jSession.GetClass("java/io/File")
    Set getFileObj = fileClass.CreateObject("(Ljava/lang/String;)V", fileName )
    End Function
    End Class
    вызов:
    Код:
    Sub Initialize
    Dim md5 As New MD5Digest()
    Print md5.getFileHash("c:\killme.jpg")
    End Sub
     
  13. lmike

    lmike нет, пердело совершенство
    Lotus team

    Репутация:
    3
    Регистрация:
    27 авг 2008
    Сообщения:
    6.406
    Симпатии:
    346
    небольшой акцент - бинарное сопоставление файлов не всегда пригодно...
    например надо сопоставить текст, а букивки разного регистра...
    с т.з. текста - мало изменений (или можно на них забить), а вот бинарно - разная инфа
     
  14. TIA

    TIA :-)
    Lotus team

    Репутация:
    0
    Регистрация:
    15 май 2009
    Сообщения:
    790
    Симпатии:
    1
    >Надо понять, изменился файл или нет.

    Решение на чистом LS:
    1. Поле с файлом копируем во временный док (физически скопируется лишь ярлык, так что быстро даже для больших файлов).
    2. Ставим полю isSigned, если в исходном документе не было
    3. Подписываем временный док
    4. Удаляем все поля кроме $Signature
    5. Пользователь меняет/не меняет файл
    6. Поле с файлом копируем в тот же временный док
    7. Ставим полю isSigned, если в исходном документе не было
    8. Проверяем подпись. Если верна -- файл не менялся (doc.Siger<>""), иначе менялся
     
  15. lmike

    lmike нет, пердело совершенство
    Lotus team

    Репутация:
    3
    Регистрация:
    27 авг 2008
    Сообщения:
    6.406
    Симпатии:
    346
    это если файл в домине...
    а не "внешний" (типа с ресурса в тырнете или диска)
    возможны и др. ограничения - типа файл требуется выложить на диск, где с ним будут работать др. приложения (не факт что писать)
     
  16. turumbay

    Репутация:
    0
    Регистрация:
    13 мар 2009
    Сообщения:
    625
    Симпатии:
    2
    а дата модификации не участвует в подписи? выгружаю файл, открываю текстовым редактором, жму ctrl+s, цепляю назад. контент не изменился. подпись будет верна?
     
  17. VladSh

    VladSh начинающий
    Lotus team

    Репутация:
    0
    Регистрация:
    11 дек 2009
    Сообщения:
    1.248
    Симпатии:
    2
    lmike, turumbay, TIA
    Ребята, спасибо всем! Щедро поделился плюсиками ))
    именно

    И вопрос напоследок: всё-таки, почему при открытии
    stream.Open(sFilePathFull, "Binary")
    stream.ReadText() берёт всего лишь 172 символа из бинарника? Кстати Unicode взял 1010 ))

    P.S. turumbay
    В LS-классе везде вставил "Me." для дополнительного контроля при НЕиспользовании Option Declare.
    Т.е. такой код:
    Код:
    getFileHash = getMD5DigestClass().digest( getFileObj(fileName) )
    стал таким:
    Код:
    Me.getFileHash = Me.getMD5DigestClass().digest(Me.getFileObj(fileName))
    Вообще атрибуты файла в подписи не участвуют, а как оно в Лотусе, это большой вопрос...)
     
  18. lmike

    lmike нет, пердело совершенство
    Lotus team

    Репутация:
    3
    Регистрация:
    27 авг 2008
    Сообщения:
    6.406
    Симпатии:
    346
    ключевое здесь - stream.ReadText()
    суваем длл, а читаем техт, кот. не воспринимает, адекватно, бинарные данные, и EOF тесктового файла может "отличаться" от физического (если файл бинарный)
    просто часть данных - нечитабельные символы, часть командные (как их интетрипирует реализация от ИИБМ - ненаю)
     
  19. VladSh

    VladSh начинающий
    Lotus team

    Репутация:
    0
    Регистрация:
    11 дек 2009
    Сообщения:
    1.248
    Симпатии:
    2
    Какой тогда нужен для правильного чтения бинарника? EOL_NONE (5)?
     
  20. lmike

    lmike нет, пердело совершенство
    Lotus team

    Репутация:
    3
    Регистрация:
    27 авг 2008
    Сообщения:
    6.406
    Симпатии:
    346
    вот этого не подскажу, но главное нужен не ReadText, а Read
     
Загрузка...

Поделиться этой страницей