以10 MB块计算文件的MD5哈希值?

时间:2017-04-26 13:18:17

标签: java hash io md5

如果您有100 MB的文件,我想为每个10 MB的段获得10个哈希值。 此外,如果说101 MB我应该得到11段MD5哈希。

我想使用自定义摘要流,它会将所有哈希值作为列表返回。

public class ChunkedDigestStream extends DigestInputStream {

    private final long chunkSize;
    private final List<String> chunkDigests = new ArrayList<>();
    private int count = 0;

    public ChunkedDigestStream(InputStream stream, MessageDigest digest, int chunkSize) {
        super(stream, digest);
        this.chunkSize = chunkSize;

    }

    @Override
    public int read(byte[] b, int off, int len) throws IOException {

       // What could be implementation here ?
}
    public List<String> getChunkDigests() {
        return chunkDigests;
    }
}

2 个答案:

答案 0 :(得分:0)

public class ChunkedDigestStream extends DigestInputStream {

    private final long chunkSize;
    private final List<String> chunkDigests = new ArrayList<>();
    private int count = 0;
    private volatile boolean isClosed = false;

    public ChunkedDigestStream(InputStream stream, MessageDigest digest, int chunkSize) {
        super(stream, digest);
        this.chunkSize = chunkSize;

    }

    @Override
    public int read(byte[] b, int off, int len) throws IOException {
        int result = in.read(b, off, len);

        if (result != -1) {
            for (int i = off; i < result; i++) {
                updateDigest(b[i]);
            }

        }

        return result;

    }

    @Override
    public int read() throws IOException {
        int ch = in.read();
        if (ch != -1) {
            updateDigest((byte) ch);
        }
        return ch;
    }

    private void updateDigest(byte _byte) {
        digest.update(_byte);
        count++;
        if (count % chunkSize == 0)
            completeChunk();
    }

    private void completeChunk() {
        chunkDigests.add(bytesToHex(digest.digest()));
        digest.reset();
        count = 0;
    }

    public List<String> getChunkDigests() {
        if (!isClosed)
            throw new IllegalStateException("ChunkedDigestStream is not closed");
        return chunkDigests;
    }

    @Override
    public void close() throws IOException {
        if (count != 0)
            completeChunk();
        isClosed = true;
        super.close();
    }

    private final static char[] hexArray = "0123456789ABCDEF".toCharArray();

    public static String bytesToHex(byte[] bytes) {
        char[] hexChars = new char[bytes.length * 2];
        for (int j = 0; j < bytes.length; j++) {
            int v = bytes[j] & 0xFF;
            hexChars[j * 2] = hexArray[v >>> 4];
            hexChars[j * 2 + 1] = hexArray[v & 0x0F];
        }
        return new String(hexChars);
    }

}

答案 1 :(得分:0)

测试客户端

public static void main(String [] args)抛出NoSuchAlgorithmException,IOException {

String test = "1234567891";

InputStream inputStream = new ByteArrayInputStream(test.getBytes());
try (ChunkedDigestStream shaStream = new ChunkedDigestStream(inputStream, MessageDigest.getInstance("MD5"),
        5)) {

    // Create byte array to read data in chunks
    byte[] byteArray = new byte[10];

    // Read file data and update in message digest
    while (shaStream.read(byteArray) != -1) {
        System.out.println(new String(byteArray));
    }

    shaStream.close();
    System.out.println(shaStream.getChunkDigests());
}

}