有没有办法从maven构建中获得一致的MD5 Hash?

时间:2015-02-23 16:42:52

标签: java maven md5sum

我可以在一组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);
    }
}

2 个答案:

答案 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();
    }
}