我可以在一组jar / war文件中连续运行5次相同的maven构建,而不对它们中的任何一个进行任何更改,但每次我在每个jar / war文件上都获得不同的MD5哈希。我希望java编译器每次都能生成相同的哈希值。是否有任何文件会影响我可以排除的散列,每次给我相同的散列?或者只是编译器每次都不以相同的方式编译相同的代码?
使用以下代码生成哈希:
public static String getHash(File file) throws FileNotFoundException, IOException {
if(file == null || !file.isFile()) {
return "";
}
FileInputStream in = null;
try {
in = new FileInputStream(file);
byte [] bytes = toByteArray(in);
return getHash(bytes);
} catch(Exception e) {
Logging.log("Unable to get MD5 hash for file: " + ile.getName());
} finally {
StreamUtils.close(in);
}
return "";
}
public static String getHash(byte[] bytes) {
MessageDigest digest = getMessageDigest();
byte[] hash = digest.digest(bytes);
StringBuilder builder = new StringBuilder();
for (int val : hash) {
builder.append(Integer.toHexString(val & 0xff));
}
return builder.toString();
}
private static MessageDigest getMessageDigest() {
try {
return MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
}
答案 0 :(得分:4)
jar或war文件是一个zip文件。 zip文件包含zip条目。 zip条目包含有关文件的元数据,如创建和修改时间。
您应该将生成的jar / war文件的每个文件的内容传递给您的哈希,总是以相同的顺序。
答案 1 :(得分:1)
尝试此代码,它将扫描jar中的每个文件并生成MD5签名
尽管它没有很好的优化
import java.io.IOException;
import java.io.InputStream;
import java.security.DigestInputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
public class MD5forjar {
public static String getMD5forjar(String fileName) throws IOException, NoSuchAlgorithmException {
ZipFile zipFile = new ZipFile(fileName);
Enumeration<? extends ZipEntry> entries = zipFile.entries();
MessageDigest sha = MessageDigest.getInstance("md5");
Map<String, String> fileMap = new HashMap<String, String>();
while (entries.hasMoreElements()) {
ZipEntry entry = entries.nextElement();
System.out.println(entry.getName());
InputStream stream = zipFile.getInputStream(entry);
DigestInputStream dig = new DigestInputStream(stream, sha);
byte[] buffer = new byte[4096];
int count = 0;
while (dig.read(buffer) > -1) {
count++;
}
MessageDigest digest = dig.getMessageDigest();
dig.close();
byte[] md5 = digest.digest();
StringBuilder sb = new StringBuilder();
for (byte b : md5) {
sb.append(String.format("%02X", b));
}
String checkSum = sb.toString();
fileMap.put(entry.getName(), checkSum);
}
SortedSet<String> sorted = new TreeSet<String>(fileMap.keySet());
StringBuffer buff = new StringBuffer();
for (String key : sorted) {
System.out.println(key);
if (!key.endsWith("pom.properties"))
buff.append(fileMap.get(key));
}
MessageDigest md = MessageDigest.getInstance("md5");
md.update(buff.toString().getBytes());
byte[] digest = md.digest();
StringBuffer sb = new StringBuffer();
for (byte b : digest) {
sb.append(String.format("%02x", b & 0xff));
}
return sb.toString();
}
}