【问题标题】:md5 file checksum from specific bytes来自特定字节的 md5 文件校验和
【发布时间】:2012-02-04 13:08:35
【问题描述】:

我想从文件中的特定字节创建一个 md5 校验和。 校验和将来自文件的 100 个字节。

我写了这段代码:

public static String getMD5ChecksumByFlash(String filename) throws Exception {
    InputStream fis = new FileInputStream(filename);
    byte[] buffer = new byte[1];
    MessageDigest complete = MessageDigest.getInstance("MD5");

    int passes = fis.available() / 100;
    int currentOffset = 0;
    int readBytes = -1;

    do {
        System.out.println("0a "+currentOffset);
        System.out.println("0b "+readBytes);
        readBytes = fis.read(buffer, currentOffset, 1);
        System.out.println("1 "+currentOffset);
        System.out.println("2 "+readBytes);
        if ( readBytes!=-1 ) {
            complete.update(buffer, 0, readBytes);
            currentOffset += passes;
            System.out.println("4 "+readBytes);
        }
        System.out.println("3 "+currentOffset);
        System.out.println("5 "+readBytes);
    } while ( readBytes!=-1 );
    fis.close();

    byte[] b = complete.digest();
    String result = "";
    for (int i = 0; i < b.length; i++) {
        result += Integer.toString((b[i] & 0xff) + 0x100, 16).substring(1);
    }
    return result;
}

但它不起作用:/ 它返回:

0a 0
0b -1
1 0
2 1
4 1
3 93928
5 1
0a 93928
0b 1
null

怎么了?

附言。 该文件不是 1 字节文件 - 它是 pidgin-2.10.1.exe

【问题讨论】:

  • 代码有意义。它尝试一次将一个字节读入缓冲区,在位置 0、(filesize*1/10)、(filesize*2/10) 等处,以从各种偏移量创建 100 个字节的 MD5 总和。但似乎 Java 从文件偏移量 0 到文件偏移量 93928 寻找一些问题。
  • 您意识到您仍然只会从文件的开头读取,对吧?你不是在寻找或类似的东西......
  • @Jon:查看docs.oracle.com/javase/1.4.2/docs/api/java/io/… 的文档,这应该是因为currentOffset 被传递给read 函数。
  • @schnaader:这是字节数组的偏移量,而不是文件。而且字节数组只有1长,所以没有意义。
  • @schnaader 再次阅读文档。 off 参数是字节数组的偏移量,而不是文件的偏移量。 (有趣的是,它下面的函数正是你想要的)

标签: java byte md5 checksum


【解决方案1】:

在 cmets 中进行了一些澄清后,看起来传递给 read 函数的偏移量指定了 array 中的偏移量,而不是 文件。这就是为什么你在那里得到null 并抛出异常的原因。因此,您可以通过将 read 调用替换为以下代码来更正代码:

readBytes = fis.read(buffer, 0, 1);
fis.skip(passes - 1);

稍微不同但更完整的方法是:

public static String getMD5ChecksumByFlash(String filename) throws Exception {
    InputStream fis = new FileInputStream(filename);
    byte[] buffer = new byte[100];
    MessageDigest complete = MessageDigest.getInstance("MD5");

    int passes = fis.available() / 100;
    int currentOffset = 0;
    int readBytes = 0;

    for (int i = 0; i < 100; i++) {
        readBytes += fis.read(buffer, i, 1);
        // TODO: Check for I/O errors
        fis.skip(passes - 1);
    }
    fis.close();

    complete.update(buffer, 0, readBytes);

    byte[] b = complete.digest();
    String result = "";
    for (int i = 0; i < b.length; i++) {
        result += Integer.toString((b[i] & 0xff) + 0x100, 16).substring(1);
    }
    return result;
}

【讨论】:

    【解决方案2】:

    好吧,这只是一种简单的方法,无需进行可靠解决方案所需的所有错误检查、循环和大小检查。这将每 100 个字节读取 1 个字节到字节缓冲区。

    byte[] arr = new byte[100];
    for (int i = 0; i < arr.length; i++) {
        is.read(arr, i, 1);
        is.skip(99);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-06-21
      • 2012-05-18
      • 1970-01-01
      • 1970-01-01
      • 2023-04-03
      • 1970-01-01
      相关资源
      最近更新 更多