Получение MD5-хеш-суммы файла в Java
Я пытаюсь использовать Java для получения контрольной суммы MD5 файла. Я был действительно удивлён, но не смог найти ничего, что объясняло бы, как получить контрольную сумму MD5 для файла.
Как это сделать?
5 ответ(ов)
java.security.DigestInputStream
— это декоратор для входного потока, который позволяет вам вычислять дайджест, используя входной поток так, как вы обычно это делаете, без необходимости делать дополнительный проход по данным.
Вот пример кода, который демонстрирует, как использовать DigestInputStream
для расчёта MD5-хеша файла:
MessageDigest md = MessageDigest.getInstance("MD5");
try (InputStream is = Files.newInputStream(Paths.get("file.txt"));
DigestInputStream dis = new DigestInputStream(is, md))
{
/* Чтение декорированного потока (dis) до конца файла как обычно... */
}
byte[] digest = md.digest();
В этом коде мы создаём экземпляр MessageDigest
для алгоритма MD5, затем оборачиваем входной поток is
в декоратор DigestInputStream
, передавая ему md
для вычисления дайджеста. После того как поток будет прочитан до конца, мы можем получить массив байтов с дайджестом, вызвав метод digest()
на нашем экземпляре MessageDigest
. Это позволяет вам не беспокоиться о том, чтобы читать данные дважды: один раз для чтения и второй раз для вычисления хеша.
Чтобы сравнить контрольную сумму файла с ожидаемым значением, вы можете использовать NIO2 (Java 7+) без сторонних библиотек. Вот пример кода:
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.MessageDigest;
import javax.xml.bind.DatatypeConverter;
public class ChecksumExample {
public static void main(String[] args) throws Exception {
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");
}
}
Обратите внимание на следующие шаги:
- Используем
Files.readAllBytes
для чтения содержимого файла в массив байтов. - С помощью
MessageDigest.getInstance("MD5")
создаем хэш-объект для MD5. - Вычисляем хэш с помощью метода
digest()
. - Преобразуем полученный хэш в шестнадцатеричную строку с помощью
DatatypeConverter.printHexBinary()
. - Сравниваем ожидаемую и фактическую контрольные суммы и выводим результат.
Этот код должен корректно работать, если файл существует по указанному пути и контрольная сумма задана в правильном формате. Не забудьте обработать исключения, которые могут возникнуть при работе с файлами и хэшированием.
Конечно! Вот перевод вашего текста в стиле ответа на вопрос на StackOverflow:
Если у вас уже есть зависимости Spring и Apache Commons, или вы планируете их добавить, вы можете использовать одну строчку кода для вычисления MD5-хеша файла:
DigestUtils.md5DigestAsHex(FileUtils.readFileToByteArray(file));
Если вы хотите использовать только Apache Commons (благодарность @duleshi):
DigestUtils.md5Hex(FileUtils.readFileToByteArray(file));
Надеюсь, это поможет кому-то!
Вы можете использовать следующий простой метод для вычисления MD5-хэш-суммы файла в Java 7 без использования сторонних библиотек:
String 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
.
Ваш код на Java вычисляет MD5-хеш для файла c:\apache\cxf.jar
. Вот краткое объяснение того, как он работает:
- Вы создаете экземпляр
MessageDigest
для алгоритма MD5. - Открываете
FileInputStream
для чтения файла. - Читаете файл по частям (по 1024 байта) в массив
dataBytes
до тех пор, пока не достигнете конца файла. - Обновляете объект
MessageDigest
данными, которые вы считали. - После завершения чтения вы вычисляете финальный хеш с помощью метода
digest()
. - Затем вы преобразуете байты хеша в шестнадцатеричную строку и выводите результат на экран.
Вот как это выглядит на русском:
public static void main(String[] args) throws Exception {
MessageDigest md = MessageDigest.getInstance("MD5"); // Создаем объект для вычисления 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()); // Выводим полученный хеш
}
Если вам нужна более подробная информация, вы можете ознакомиться с этой статьей.
Инициализация ArrayList в одну строчку
Почему нет ConcurrentHashSet, если есть ConcurrentHashMap?
Как объявить массив в одну строку?
Загрузка JDK Java на Linux через wget приводит к отображению страницы лицензии вместо установки
Создание репозитория Spring без сущности