Search code examples
functional-programmingerlangelixirmd5checksum

How can I calculate a file checksum in Elixir?


I need to calculate the md5 sum of a file in Elixir, how can this be achieved? I would expect that something like:

iex(15)> {:ok, f} = File.open "file"
{:ok, #PID<0.334.0>}
iex(16)> :crypto.hash(:md5, f)
** (ArgumentError) argument error
             :erlang.iolist_to_binary(#PID<0.334.0>)
    (crypto) crypto.erl:225: :crypto.hash/2

But clearly it doesn't work..

The documentation of Mix.Utils tells about read_path/2, but it didn't worked either.

iex(22)> Mix.Utils.read_path("file", [:sha512])  
{:ok, "Elixir"} #the expected was {:checksum, "<checksum_value>"}

Is there any library that provides such functionality in a easy way?


Solution

  • In case anyone else finds this question and misses @FredtheMagicWonderDog's comment . . .

    Check out this blog posting: http://www.cursingthedarkness.com/2015/04/how-to-get-hash-of-file-in-exilir.html

    And here's the relevant code:

    File.stream!("./known_hosts.txt",[],2048) 
    |> Enum.reduce(:crypto.hash_init(:sha256),fn(line, acc) -> :crypto.hash_update(acc,line) end ) 
    |> :crypto.hash_final 
    |> Base.encode16 
    
    
    #=> "97368E46417DF00CB833C73457D2BE0509C9A404B255D4C70BBDC792D248B4A2" 
    

    NB: I'm posting this as community wiki. I'm not trying to get rep points; just trying to ensure the answer isn't buried in comments.