Zip-файл md5 Контрольная сумма - каждый раз разные
У меня есть приложения для Android, которые получают контрольную сумму md5 zip-файла. Я использую его для сравнения файла с файлом на сервере. Моя проблема в том, что каждый раз, когда я пытаюсь сгенерировать md5 для одного и того же файла, контрольная сумма отличается. Я публикую свои методы здесь. Можете ли вы сказать мне, что не так?
private static String fileMD5(String filePath) throws NoSuchAlgorithmException, IOException {
InputStream inputStream = null;
try {
inputStream = new FileInputStream(filePath);
byte[] buffer = new byte[1024];
MessageDigest digest = MessageDigest.getInstance("MD5");
int numRead = 0;
while (numRead != -1) {
numRead = inputStream.read(buffer);
if (numRead > 0)
digest.update(buffer, 0, numRead);
}
byte [] md5Bytes = digest.digest();
return convertHashToString(md5Bytes);
} catch (Exception e) {
return "ERROR";
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (Exception e) { }
}
}
}
private static String convertHashToString(byte[] md5Bytes) {
String returnVal = "";
for (int i = 0; i < md5Bytes.length; i++) {
returnVal += Integer.toString(( md5Bytes[i] & 0xff ) + 0x100, 16).substring(1);
}
return returnVal;
}
2 ответа
Я пытаюсь решить ту же проблему. Я не знаю, как это решить, но я знаю причину:).
Причина в том, что zip-файл содержит как минимум временную информацию о файлах. И это то, что вы измените md5sum. Каждая запись zip одинакова, но это результат изменения информации метаданных для md5.
Возможно, вы уже нашли ответ где-то еще.
Как упомянул @michal-Šiplák
Причина в том, что zip-файл содержит как минимум информацию о временных метках файлов. И это то, что меняет ваш md5sum. Каждая запись zip одинакова, но этот результат изменения информации метаданных для md5.
Чтобы иметь согласованный md5, вам нужно удалить эту переменную и зафиксировать ее как константу. Пример ниже
fun pack(sourceDir: File, zipFile: File) {
ZipOutputStream(zipFile.outputStream()).use { zs ->
val sourcePath = sourceDir.toPath()
Files.walk(sourcePath)
.filter { path -> path.isDirectory().not() }
.forEach { path ->
zs.putNextEntry(createZipEntry(path, sourcePath))
Files.copy(path, zs)
zs.closeEntry()
}
}
}
fun createZipEntry(filePath: Path, sourcePath: Path): ZipEntry {
val zipEntry = ZipEntry(sourcePath.relativize(filePath).toString())
zipEntry.time = 0
return zipEntry
}
ключевая строка здесьzipEntry.time = 0
что делает zip-файл метаданных постоянным.