vlang 中文件 md5sum 的内存高效计算

Memory efficient computation of md5sum of a file in vlang

以下代码将文件读入字节并计算字节数组的 md5sum。它有效,但我想在 V 中找到一个需要更少 RAM 的解决方案。 感谢您的评论!

import os
import crypto.md5

b := os.read_bytes("file.txt") or {panic(err)}

s := md5.sum(b).hex()

println(s)

我也试过没有成功:

import os
import crypto.md5
import io

mut f := os.open_file("file.txt", "r")?

mut h := md5.new()

io.cp(mut f, mut h)?

s := h.sum().hex()

println(s) // does not return the correct md5sum

总结一下我从评论中学到的东西:

  • V 是一种带有类型参数的编程语言
  • md5.sum 采用字节数组参数,而不是字节序列,例如从文件中读取 as-you-go.
  • md5.sum
  • 别无选择

因此,您必须自己实施 MD5。也许标准库是开源的,您可以在此基础上进行构建!或者,您可以只绑定 MD5 的任何现有(例如 C)实现,并在读取它们时以字节为单位,以 512 位 = 2⁶ 字节的块为单位。

编辑:我不知道V,所以我很难判断,但看起来Digest.write将是一种连续推送数据的方法MD5计算。也许与 while 循环一起从文件中读取字节是解决方案?

好的。这就是您要找的。它产生与 md5sum 相同的结果,只是稍微慢一点。 block_size 与使用的内存量和计算校验和的速度成反比。减少 block_size 会降低内存占用,但计算时间会更长。增加 block_size 会产生相反的效果。我在 2GB 的 manjaro 光盘映像上进行了测试,可以确认内存使用率非常低。

注意:在没有 -prod 标志的情况下,这似乎确实执行得明显较慢。 V 编译器进行了特殊优化,以便 运行 更快地进行生产构建。

import crypto.md5
import io
import os

fn main() {
    println(hash_file('manjaro.img')?)
}

const block_size = 64 * 65535

fn hash_file(path string) ?string {
    mut file := os.open(path)?
    defer {
        file.close()
    }
    mut buf := []u8{len: block_size}
    mut r := io.new_buffered_reader(reader: file)
    mut digest := md5.new()
    for {
        x := r.read(mut buf) or { break }
        digest.write(buf[..x])?
    }
    return digest.checksum().hex()
}