大文件要用 File.stream!
來分段讀取, 不然一會兒讀到內存裏會撐爆內存.linux
erlang 的 :crypto
標準庫中有內置 :crypto.hash_init/1
:crypto.hash_update/2
和 :crypto.hash_final/1
這三個函數, 幫助咱們進行分步的哈希運算.macos
因此最後能夠寫成:bash
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"