philomena/lib/philomena_media/sha512.ex

42 lines
1.1 KiB
Elixir

defmodule PhilomenaMedia.Sha512 do
@moduledoc """
Streaming SHA-512 processor.
"""
@chunk_size 10_485_760
@doc """
Generate the SHA2-512 hash of the file at the given path as a string.
The file is processed in 10MiB chunks.
## Example
iex> Sha512.file("image.png")
"97fd5243cd39e225f1478097acae71fbbff7f3027b24f0e6a8e06a0d7d3e6861cd05691d7470c76e7dfc4eb30459a906918d5ba0d144184fff02b8e34bd9ecf8"
"""
@spec file(Path.t()) :: String.t()
def file(path) do
hash_ref = :crypto.hash_init(:sha512)
path
|> stream_file()
|> Enum.reduce(hash_ref, &:crypto.hash_update(&2, &1))
|> :crypto.hash_final()
|> Base.encode16(case: :lower)
end
if Version.match?(System.version(), ">= 1.16.0") do
# `stream!/2` was added in Elixir 1.16 to accept a shortened form,
# where we only need to specify the size of each stream chunk
defp stream_file(file) do
File.stream!(file, @chunk_size)
end
else
# Use legacy stream/3 for older Elixir versions
defp stream_file(file) do
File.stream!(file, [], @chunk_size)
end
end
end