如何计算自定义输出流中的消息摘要?

时间:2015-04-07 16:26:24

标签: java outputstream message-digest

我想实现可以生成OutputStream的{​​{1}}。同样,我已经MessageDigests实施了here,它可以正常工作并扩展InputStream

问题在于:如果我延长FilterInputStream,则校验和不匹配。如果我使用FilterOutputStream它可以正常工作(虽然这不是我想要使用的流,因为我希望它比那更通用)。

FileOutputStream

我的测试用例(使用public class MultipleDigestOutputStream extends FilterOutputStream { public static final String[] DEFAULT_ALGORITHMS = { EncryptionConstants.ALGORITHM_MD5, EncryptionConstants.ALGORITHM_SHA1 }; private Map<String, MessageDigest> digests = new LinkedHashMap<>(); private File file; public MultipleDigestOutputStream(File file, OutputStream os) throws NoSuchAlgorithmException, FileNotFoundException { this(file, os, DEFAULT_ALGORITHMS); } public MultipleDigestOutputStream(File file, OutputStream os, String[] algorithms) throws NoSuchAlgorithmException, FileNotFoundException { // super(file); // If extending FileOutputStream super(os); this.file = file; for (String algorithm : algorithms) { addAlgorithm(algorithm); } } public void addAlgorithm(String algorithm) throws NoSuchAlgorithmException { MessageDigest digest = MessageDigest.getInstance(algorithm); digests.put(algorithm, digest); } public MessageDigest getMessageDigest(String algorithm) { return digests.get(algorithm); } public Map<String, MessageDigest> getDigests() { return digests; } public String getMessageDigestAsHexadecimalString(String algorithm) { return MessageDigestUtils.convertToHexadecimalString(getMessageDigest(algorithm)); } public void setDigests(Map<String, MessageDigest> digests) { this.digests = digests; } @Override public void write(int b) throws IOException { super.write(b); System.out.println("write(int b)"); for (Map.Entry entry : digests.entrySet()) { int p = b & 0xFF; byte b1 = (byte) p; MessageDigest digest = (MessageDigest) entry.getValue(); digest.update(b1); } } @Override public void write(byte[] b) throws IOException { super.write(b); for (Map.Entry entry : digests.entrySet()) { MessageDigest digest = (MessageDigest) entry.getValue(); digest.update(b); } } @Override public void write(byte[] b, int off, int len) throws IOException { super.write(b, off, len); for (Map.Entry entry : digests.entrySet()) { MessageDigest digest = (MessageDigest) entry.getValue(); digest.update(b, off, len); } } @Override public void close() throws IOException { super.close(); } } md5sum检查了断言的校验和):

sha1sum

请问您可以提出问题以及如何解决问题?非常感谢提前!

2 个答案:

答案 0 :(得分:2)

如果您使用的是java 7或更高版本,则可以使用DigestOutputstream

<强>更新

您可以使用抽象MessageDigest类来包装多个MessageDigest实例。

某些代码

    import java.security.DigestException;
    import java.security.MessageDigest;
    import java.security.NoSuchAlgorithmException;


    public class DigestWrapper extends MessageDigest
    {
        private final MessageDigest md5;
        private final MessageDigest sha1;

        // some methods missing.
        // I just implemeted them throwing a RuntimeException.

        public DigestWrapper() throws NoSuchAlgorithmException
        {
            super(null);
            sha1 = MessageDigest.getInstance("sha-1");
            md5 = MessageDigest.getInstance("md5");
        }

        public byte[] getMD5Digest()
        {
            return md5.digest();
        }

        public byte[] getSHA1Digest()
        {
            return sha1.digest();
        }

        @Override
        public int digest(byte[] buf, int offset, int len) throws DigestException
        {
            md5.digest(buf, offset, len);
            sha1.digest(buf, offset, len);
            return 0;
        }

        @Override
        public byte[] digest(byte[] input)
        {
            md5.digest(input);
            sha1.digest(input);
            return input;
        }

        @Override
        public void reset()
        {
            md5.reset();
            sha1.reset();
        }

        @Override
        public void update(byte input)
        {
            md5.update(input);
            sha1.update(input);
        }

        @Override
        public void update(byte[] input, int offset, int len)
        {
            md5.update(input, offset, len);
            sha1.update(input, offset, len);
        }

        @Override
        public void update(byte[] input)
        {
            md5.update(input);
            sha1.update(input);
        }

    }

答案 1 :(得分:1)

我在Github上创建了一个项目,其中包含MultipleDigestInputStreamMultipleDigestOutputStream here的实现。

要检查代码的使用方式,请查看以下测试:

请告诉我,如果有足够的兴趣,我可以将其发布并发布到Maven Central。