【问题标题】:Getting MD5 Hash of File from URL从 URL 获取文件的 MD5 哈希
【发布时间】:2012-11-14 17:57:56
【问题描述】:

我得到的结果是相同类型的文件返回相同的 md5 哈希值。例如,两个不同的 jpg 给了我相同的结果。但是,jpg 和 apk 会给出不同的结果。

这是我的代码...

public static String checkHashURL(String input) {
    try {
        MessageDigest md = MessageDigest.getInstance("MD5");
        InputStream is = new URL(input).openStream();

        try {
            is = new DigestInputStream(is, md);

            int b;

            while ((b = is.read()) > 0) {
                ;
            }
        } finally {
            is.close();
        }
        byte[] digest = md.digest();
        StringBuffer sb = new StringBuffer();

        for (int i = 0; i < digest.length; i++) {
            sb.append(
                    Integer.toString((digest[i] & 0xff) + 0x100, 16).substring(
                            1));
        }
        return sb.toString();

    } catch (Exception ex) {
        throw new RuntimeException(ex);
    }
}

【问题讨论】:

  • 您确定要散列 jpg 文件而不是 404 错误与 DNS 未找到错误吗?
  • 我的猜测是只有文件数据的标题标签被读取和散列,因此导致相似类型的文件看起来相等。我建议调试正在读取的数据。

标签: java android md5


【解决方案1】:

这个坏了:

while ((b = is.read()) > 0)

您的代码将在流的第一个字节 0 处停止。如果两个文件在第一个 0 字节之前具有相同的值,您将失败。如果你真的想要调用read的一次字节版本,你想要:

while (is.read() != -1) {}

parameterless InputStream.read() 方法在到达流的末尾时返回 -1。

(无需为b 赋值,因为您没有使用它。)

最好一次读取一个缓冲区:

byte[] ignoredBuffer = new byte[8 * 1024]; // Up to 8K per read
while (is.read(ignoredBuffer) > 0) {}

这一次条件是有效的,因为InputStream.read(byte[]) 只会在你传入一个空缓冲区时返回 0。否则,它将尝试读取至少一个字节,如果已到达流的末尾,则返回读取的数据长度或 -1。

【讨论】:

  • @user1288686:它真的解决了这个问题吗? :)
  • 是的。还有一个问题..因为我正在逐字节读取文件,这会占用与下载文件相同的带宽吗?我想知道,因为我正在开发这个来验证我的 android 应用程序下载的更新,并且受到运营商带宽限制的限制。
  • @user1288686:无论您是逐字节读取还是一次读取缓冲区,您仍在获取整个文件,所以是的。它正在下载文件,只是没有将其保存到磁盘。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-11-11
  • 2012-05-28
  • 1970-01-01
  • 2012-10-31
  • 1970-01-01
  • 2012-08-17
  • 2016-06-24
相关资源
最近更新 更多