【问题标题】:CRC calculation takes too much timeCRC计算耗时过长
【发布时间】:2023-11-21 05:30:01
【问题描述】:

在我正在开发的 Android 应用上,我可以通过其 CRC32、MD5 或 SHA1 识别文件(我有包含这些列表的 xml 文件)。

我读到 CRC32 的计算速度更快,所以我决定使用这个,但是计算 4MB 文件的 CRC32 大约需要 3 分钟,而且我需要在更多甚至更大的文件上进行计算更短的时间。这是具有双 1.5GHz CPU 和 1GB RAM 的设备的常规时间吗?如果不是,可能是由于堆限制吗?如果我使用Process.exec 编译原生 C 以通过 shell 计算 CRC 会有所改善吗?

编辑代码: 我添加了一个 BufferedInputStream,现在大约需要 7 秒。但是 35MB 文件需要 1 分钟。

InputStream fi = new BufferedInputStream(new FileInputStream(f));

int gByte = 0;
CRC32 gCRC = new CRC32();
while ((gByte = fi.read()) != -1) {
    gCRC.update(gByte);
}
fi.close();

【问题讨论】:

  • 请添加您的校验和代码,因为它可能会导致错误的加密 API 使用...
  • crc32如何计算?
  • 我 30 岁的微型计算机配备 2MHz 8 位 6502 处理器,可以以大致相同的速率计算 CRC32。对于现代设备来说,速度慢得离谱。
  • 发布一些代码。几乎可以肯定,您将时间花在 I/O 上,而不是 CRC 计算上。
  • 完全符合怀疑。添加一个 BufferedInputStream,或者一次读入一个 byte[] 数组而不是一个字节,你的问题就会消失。

标签: java android crc


【解决方案1】:
byte[] buf = new byte[1024*64];
while ((gByte = fi.read(buf)) > 0) {
    gCRC.update(buf, 0, gByte);
}
fi.close();

java nio 甚至可能对大文件有更多帮助。

【讨论】:

    【解决方案2】:

    一个体面的软件 CRC-32 实现应该能够在现代处理器上每秒处理超过 1 GB 的数据。我在 2 GHz i7 上获得 1.2 GB/s。

    您需要向 CRC 算法提供大块。 不要一次输入一个字节。

    顺便说一句,我使用硬件 crc32 指令在我的 2 GHz i7 上获得了 18 GB/s。

    md5 和 sha1 均约为 0.35 GB/s。 sha256 约为 0.18 GB/s。

    【讨论】: