Получение контрольной суммы MD5 в Java - PullRequest
462 голосов
/ 20 ноября 2008

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

Как это сделать?

Ответы [ 21 ]

508 голосов
/ 20 ноября 2008

Существует декоратор входного потока, java.security.DigestInputStream, так что вы можете вычислить дайджест при использовании входного потока, как обычно, вместо того, чтобы делать дополнительный проход по данным.

MessageDigest md = MessageDigest.getInstance("MD5");
try (InputStream is = Files.newInputStream(Paths.get("file.txt"));
     DigestInputStream dis = new DigestInputStream(is, md)) 
{
  /* Read decorated stream (dis) to EOF as normal... */
}
byte[] digest = md.digest();
278 голосов
/ 29 мая 2010

Использование DigestUtils из Кодек Apache Commons Библиотека:

try (InputStream is = Files.newInputStream(Paths.get("file.txt"))) {
    String md5 = org.apache.commons.codec.digest.DigestUtils.md5Hex(is);
}
155 голосов
/ 20 ноября 2008

В Java-How-to есть пример использования MessageDigest класса.

Проверьте на этой странице примеры использования CRC32 и SHA-1.

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();
       }
   }
}
85 голосов
/ 24 декабря 2010

API com.google.common.hash предлагает:

  • Унифицированный удобный API для всех хеш-функций
  • Seedable 32- и 128-битные реализации murmur3
  • Адаптеры md5 (), sha1 (), sha256 (), sha512 () изменяют только одну строку кода для переключения между ними и бормотают.
  • goodFastHash (int bits), для тех случаев, когда вам все равно, какой алгоритм вы используете
  • Общие утилиты для экземпляров HashCode, такие как combOrdered / combUnordered

Прочтите руководство пользователя ( Объяснение ввода-вывода , Объяснение хеширования ).

Для вашего варианта использования Files.hash() вычисляет и возвращает значение дайджеста для файла.

Например, расчет дайджеста (измените SHA-1 на MD5, чтобы получить дайджест MD5)

HashCode hc = Files.asByteSource(file).hash(Hashing.sha1());
"SHA-1: " + hc.toString();

Обратите внимание, что намного быстрее, чем , поэтому используйте , если вам не нужна криптографически безопасная контрольная сумма. Также обратите внимание, что не следует использовать для хранения паролей и т. П., Так как это просто для взлома паролей, для паролей используйте , или вместо.

Для долгосрочной защиты с помощью хэшей Схема подписи Меркле повышает безопасность, а Исследовательская группа по постквантовой криптографии, спонсируемая Европейской комиссией, рекомендовала использовать эту криптографию для долговременной защиты от квантовых компьютеров ( исх ).

Обратите внимание, что имеет более высокую частоту столкновений, чем другие.

51 голосов
/ 07 октября 2014

Использование nio2 (Java 7+) и отсутствие внешних библиотек:

byte[] b = Files.readAllBytes(Paths.get("/path/to/file"));
byte[] hash = MessageDigest.getInstance("MD5").digest(b);

Чтобы сравнить результат с ожидаемой контрольной суммой:

String expected = "2252290BC44BEAD16AA1BF89948472E8";
String actual = DatatypeConverter.printHexBinary(hash);
System.out.println(expected.equalsIgnoreCase(actual) ? "MATCH" : "NO MATCH");
36 голосов
/ 09 октября 2012

Guava теперь предоставляет новый, согласованный API-интерфейс хэширования, который намного удобнее для пользователя, чем различные API-интерфейсы хэширования, предоставляемые в JDK. См. Объяснение хеширования . Для файла вы можете легко получить сумму MD5, CRC32 (с версией 14.0+) или многие другие хеши:

HashCode md5 = Files.hash(file, Hashing.md5());
byte[] md5Bytes = md5.asBytes();
String md5Hex = md5.toString();

HashCode crc32 = Files.hash(file, Hashing.crc32());
int crc32Int = crc32.asInt();

// the Checksum API returns a long, but it's padded with 0s for 32-bit CRC
// this is the value you would get if using that API directly
long checksumResult = crc32.padToLong();
28 голосов
/ 20 марта 2013

Хорошо. Я должен был добавить. Однострочная реализация для тех, кто уже имеет зависимость от Spring и Apache Commons или планирует добавить ее:

DigestUtils.md5DigestAsHex(FileUtils.readFileToByteArray(file))

Для общего доступа и опции Apache только для общего использования (credit @duleshi):

DigestUtils.md5Hex(FileUtils.readFileToByteArray(file))

Надеюсь, это кому-нибудь поможет.

23 голосов
/ 31 октября 2014

Простой подход без сторонних библиотек с использованием Java 7

String path = "your complete file path";
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(Files.readAllBytes(Paths.get(path)));
byte[] digest = md.digest();

Если вам нужно распечатать этот байтовый массив. Используйте как показано ниже

System.out.println(Arrays.toString(digest));

Если вам нужна шестнадцатеричная строка из этого дайджеста. Используйте как показано ниже

String digestInHex = DatatypeConverter.printHexBinary(digest).toUpperCase();
System.out.println(digestInHex);

где DatatypeConverter - это javax.xml.bind.DatatypeConverter

13 голосов
/ 20 ноября 2008

Я недавно должен был сделать это только для динамической строки, MessageDigest может представлять хэш различными способами. Чтобы получить сигнатуру файла, как если бы вы получили команду md5sum , мне нужно было сделать что-то вроде этого:

try {
   String s = "TEST STRING";
   MessageDigest md5 = MessageDigest.getInstance("MD5");
   md5.update(s.getBytes(),0,s.length());
   String signature = new BigInteger(1,md5.digest()).toString(16);
   System.out.println("Signature: "+signature);

} catch (final NoSuchAlgorithmException e) {
   e.printStackTrace();
}

Это, очевидно, не отвечает на ваш вопрос о том, как сделать это специально для файла, вышеупомянутый ответ прекрасно с этим справляется. Я просто потратил много времени на то, чтобы сумма выглядела так, как показывает большинство приложений, и подумал, что вы можете столкнуться с той же проблемой.

11 голосов
/ 31 декабря 2012
public static void main(String[] args) throws Exception {
    MessageDigest md = MessageDigest.getInstance("MD5");
    FileInputStream fis = new FileInputStream("c:\\apache\\cxf.jar");

    byte[] dataBytes = new byte[1024];

    int nread = 0;
    while ((nread = fis.read(dataBytes)) != -1) {
        md.update(dataBytes, 0, nread);
    };
    byte[] mdbytes = md.digest();
    StringBuffer sb = new StringBuffer();
    for (int i = 0; i < mdbytes.length; i++) {
        sb.append(Integer.toString((mdbytes[i] & 0xff) + 0x100, 16).substring(1));
    }
    System.out.println("Digest(in hex format):: " + sb.toString());
}

Или вы можете получить больше информации http://www.asjava.com/core-java/java-md5-example/

...