2012-11-14 97 views
3

我得到的结果是相同类型的文件返回相同的md5哈希值。例如两个不同的jpgs给了我相同的结果。然而,一个JPG和一个apk会给出不同的结果。从URL获取MD5哈希文件

这里是我的代码...

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); 
    } 
} 
+1

你确定是哈希jpg文件,而不是404错误与DNS未发现错误? –

+1

我的猜测是只有文件数据的标题标记正在读取和散列,因此导致类似类型的文件看起来相同。我建议调试正在读取的数据。 – Vulcan

回答

4

这被打破:

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。

+0

真棒感谢您的解释 – k1komans

+1

@ user1288686:它是否真的解决了这个问题? :) –

+0

是的,它有。还有一个问题,因为我正在逐字节读取文件,这将占用相同数量的带宽,就像下载文件一样?我想知道,因为我正在开发这个验证下载的更新到我的Android应用程序,并受到运营商带宽限制的限制。 – k1komans