Каков самый быстрый способ загрузить MD5 файла?

Я хочу загрузить MD5 из разных файлов. Я следую этому ответу, чтобы сделать это, но основная проблема заключается в том, что время, необходимое для загрузки MD5 файлов (май быть в сотнях) много.

Есть ли способ, который можно использовать для поиска MD5 файла, не занимая много времени.

Примечание. Размер файла может быть большим (до 300 МБ).

Это код, который я использую -

import java.io.*;
import java.security.MessageDigest;

public class MD5Checksum {

   public static byte[] createChecksum(String filename) throws Exception {
       InputStream fis =  new FileInputStream(filename);

       byte[] buffer = new byte[1024];
       MessageDigest complete = MessageDigest.getInstance("MD5");
       int numRead;

       do {
           numRead = fis.read(buffer);
           if (numRead > 0) {
               complete.update(buffer, 0, numRead);
           }
       } while (numRead != -1);

       fis.close();
       return complete.digest();
   }

   // see this How-to for a faster way to convert
   // a byte array to a HEX string
   public static String getMD5Checksum(String filename) throws Exception {
       byte[] b = createChecksum(filename);
       String result = "";

       for (int i=0; i < b.length; i++) {
           result += Integer.toString( ( b[i] & 0xff ) + 0x100, 16).substring( 1 );
       }
       return result;
   }

   public static void main(String args[]) {
       try {
           System.out.println(getMD5Checksum("apache-tomcat-5.5.17.exe"));
           // output :
           //  0bb2827c5eacf570b6064e24e0e6653b
           // ref :
           //  http://www.apache.org/dist/
           //          tomcat/tomcat-5/v5.5.17/bin
           //              /apache-tomcat-5.5.17.exe.MD5
           //  0bb2827c5eacf570b6064e24e0e6653b *apache-tomcat-5.5.17.exe
       }
       catch (Exception e) {
           e.printStackTrace();
       }
   }
}

person Rahulrr2602    schedule 13.01.2018    source источник
comment
попробуйте больший буфер: например 64 * 1024   -  person pskink    schedule 13.01.2018
comment
@pskink Пробовал буферизировать до 32764, но по-прежнему потребляется много галстука. Также есть ли вред от дальнейшего увеличения размера буфера?   -  person Rahulrr2602    schedule 13.01.2018
comment
Много времени уйдет на добавление строк в шестнадцатеричное преобразование. Используйте `BigInteger.toHexString()``.   -  person user207421    schedule 14.01.2018
comment
@EJP Какова вероятность столкновения?   -  person Rahulrr2602    schedule 14.01.2018


Ответы (2)


Вы не можете использовать хэши для определения какого-либо сходства контента.
Например, при создании MD5 для hellostackoverflow1 и hellostackoverflow2 вычисляются два хэша, в которых не совпадают ни один из символов строкового представления (7c35[...]85fa против b283[...]3d19). Это потому, что хэш вычисляется на основе двоичных данных файла, таким образом, два разных формата одного и того же - например. .txt и .docx одного и того же текста имеют разные хэши.

Но, как уже отмечалось, некоторая скорость может быть достигнута за счет использования нативного кода, например, NDK. Кроме того, если вы все же хотите сравнить файлы на предмет точного совпадения, сначала сравните размер в байтах, после этого используйте алгоритм хеширования с достаточной скоростью и низким риском коллизий. Как уже говорилось, CRC32 в порядке.

person Ch4t4r    schedule 14.01.2018

Вычисление хэша/CRC занимает некоторое время, так как файл должен быть прочитан полностью.

Представленный вами код createChecksum почти оптимален. Единственная часть, которую можно настроить, — это размер буфера чтения (я бы использовал размер буфера 2048 байт или больше). Однако это может дать вам увеличение скорости максимум на 1-2%.

Если это все еще слишком медленно, остается единственный вариант — реализовать хеширование на C/C++ и использовать его как собственный метод. Кроме этого, вы ничего не можете сделать.

person Robert    schedule 13.01.2018
comment
Большое спасибо за ответ. Не могли бы вы привести пример того, как это сделать, поскольку я не очень хорошо знаком с C/C++. Также нормально ли, если crc32 контрольная сумма проверяет, совпадают ли два файла или нет? - person Rahulrr2602; 13.01.2018
comment
Для проверки того, являются ли два файла одинаковыми, вы можете использовать crc32. Кстати, вы проверяете соответствие размеров файлов перед вычислением хеш-суммы? - person Ch4t4r; 13.01.2018
comment
@ Rahulrr2602: использовать md5 или crc32 на ваше усмотрение. Насколько вероятно столкновение и каковы последствия, зависит от ваших требований. Подробнее см. этот вопрос. Представление нативной реализации выходит за рамки, если у вас нет опыта работы с C. Может быть, есть существующая библиотека для Android, но я ее не знаю. - person Robert; 13.01.2018
comment
@ Ch4t4r Спасибо, но я не проверяю размер файла перед поиском MD5. Причина в том, что я хочу проверить сходство файла по содержимому, а не по размеру. Возможно ли, чтобы два разных файла имели одинаковое содержимое, но имели разный формат и, следовательно, имели разный размер? - person Rahulrr2602; 13.01.2018
comment
Вы не можете использовать хэши для определения какого-либо сходства контента. Например, при генерации MD5 для hellostackoverflow1 и hellostackoverflow2 вычисляются два хэша, в которых ни один из символов строкового представления не совпадает (7c35[...]85fa против b283[...]3d19). Это потому, что хэш вычисляется на основе двоичных данных файла, таким образом, два разных формата одного и того же - например. .txt и .docx одного и того же текста имеют разные хэши. - person Ch4t4r; 14.01.2018
comment
@Ch4t4r Большое спасибо. Реально решил мою проблему. Не могли бы вы опубликовать ответ, чтобы я мог его принять. - person Rahulrr2602; 14.01.2018