乐趣区

elixir-49-对大文件做哈希运算

大文件要用 File.stream! 来分段读取, 否则一下子读到内存里会撑爆内存.

erlang 的 :crypto 标准库中有内置 :crypto.hash_init/1 :crypto.hash_update/2:crypto.hash_final/1 这三个函数, 帮助我们进行分步的哈希运算.

所以最后可以写成:

  def sha256_file(path) when is_binary(path) do
    File.stream!(path, [], 2048)
    |> Enum.reduce(:crypto.hash_init(:sha256), &:crypto.hash_update(&2, &1))
    |> :crypto.hash_final()
    |> Base.encode16(case: :lower)
  end

验证一下:

$ openssl dgst -sha256 SwiftForth-linux-macos-eval.tgz
SHA256(SwiftForth-linux-macos-eval.tgz)= b9870ccafc0713ae80ff2ee3645592622012b6155a8a2e6a396ceb89b7845d98
iex()> BexLib.Crypto.sha256_file "/Downloads/SwiftForth-linux-macos-eval.tgz"
"b9870ccafc0713ae80ff2ee3645592622012b6155a8a2e6a396ceb89b7845d98"
退出移动版