今晚,我正在研究一个简单的解决方案,用于在流传递时进行即时md5计算。主要框架立刻就完美地运作起来了。数据被流并计算MD5-哈希值。但后来我开始在3个不同的阶段监控MD5-Hash。流前、流时和流后。结果让我大吃一惊。
最重要的MD5摘要显然被错误地计算出来。对于所有的编码,我使用了相同的Apache DigestUtils方法。但是,与其产生3倍相同的输出,我只得到了3倍的输出。
为了验证,我的构造中没有一般性错误,我还使用Apache的(...).binary.Hex类对摘要进行编码。这一次的结果和其他的结果是一致的。
流媒体前MD5 :9065793b048f4efin5ccddb34798ee19
流媒体后MD5 :9065793b048f4efin5ccddb34798ee19
由95d845ff55b5918edc8d1222045dd1cb:DigestUtils编码的流时MD5
MD5同时由binary.Hex编码:9065793b048f4efin5ccddb34798ee19
这是我非常简单的代码。
第一个类是通过主方法开始的。它调用类StreamForwarder的一个实例,并将测试字符串作为InputStream传递。就这样。
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import org.apache.commons.codec.digest.DigestUtils;
public class StreamProvider {
private static final byte[] streamContent;
static {
streamContent = "i9BjYXhrIA7FvuQ8WTIhIbgCGwfIGKfu".getBytes();
}
private static InputStream getStreamContent() {
return new ByteArrayInputStream(streamContent);
}
public static void main(String args[]) {
System.out.println("MD5 before streaming: " +
DigestUtils.md5Hex(streamContent));
StreamForwarder streamForwarder = new StreamForwarder();
streamForwarder.forwardStream(getStreamContent());
}
}StreamForwarder将InputStream封装在DigestInputStream中,并获取MessageDigest的一个实例,以便在流中计算MD5-哈希。它调用类StreamConsumer的一个实例并传递DigestInputStream。
import java.io.InputStream;
import java.security.DigestInputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.codec.digest.DigestUtils;
public class StreamForwarder {
public void forwardStream(InputStream is) throws NoSuchAlgorithmException {
MessageDigest md = MessageDigest.getInstance("MD5");
DigestInputStream dis = new DigestInputStream(is, md);
StreamConsumer streamConsumer = new StreamConsumer();
streamConsumer.printStreamContent(dis);
byte digest[] = md.digest();
String digestUtilsHexString = DigestUtils.md5Hex(digest);
String binaryHexString = new String(Hex.encodeHex(digest));
System.out.println("MD5 while streaming encoded by DigestUtils: " +
digestUtilsHexString);
System.out.println("MD5 while streaming encoded by binary.Hex: " +
binaryHexString);
}
}最后,StreamConsumer使用Apache的IOUtils读取流。
import java.io.IOException;
import java.io.InputStream;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.io.IOUtils;
public class StreamConsumer {
public void printStreamContent(InputStream is) throws IOException {
String myString = IOUtils.toString(is, "UTF-8");
System.out.println("MD5 after streaming: " +
DigestUtils.md5Hex(myString.getBytes()));
}
}正如你所看到的,它背后没有火箭科学。但是,StreamForwarder.class的输出仍然不是我所期望的关于编码HexString of DigestUtils的输出。
有人能解释一下为什么会发生这种事吗?我做错什么了吗?
提前感谢!
发布于 2016-08-23 20:56:03
这条线上的问题
String digestUtilsHexString = DigestUtils.md5Hex(digest);您有时会计算摘要- md5hex(md5(is))。你可以在bash检查一下
$ echo -n 9065793b048f4efee5ccddb34798ee19 \
| perl -pe 's/([0-9a-f]{2})/chr hex $1/gie' \
| md5sum
95d845ff55b5918edc8d1222045dd1cb -https://stackoverflow.com/questions/39110379
复制相似问题