2016-12-07 1 views
2

J'ai besoin de calculer la somme md5 d'un fichier dans Elixir, comment cela peut-il être réalisé? Je suppose que quelque chose comme:Comment puis-je calculer une somme de contrôle de fichier dans Elixir?

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 

Mais il est clair qu'il ne fonctionne pas ..

La documentation de Mix.Utils raconte la fonction read_path link, mais il n'a pas fonctionné non plus.

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

Y a-t-il une bibliothèque qui offre une telle fonctionnalité de manière simple?

+0

Article de blog de Relevent: http://www.cursingthedarkness.com/2015/04/how-to-get-hash-of-file-in-exilir.html –

Répondre

5

Si quelqu'un d'autre trouve cette question et rate le commentaire de @ FredtheMagicWonderDog. . .

Découvrez cette publication de blog: http://www.cursingthedarkness.com/2015/04/how-to-get-hash-of-file-in-exilir.html

Et voici le code correspondant:

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: Je poste ce wiki comme communautaire. Je n'essaie pas d'obtenir des points de rep. juste en essayant d'assurer la réponse n'est pas enterré dans les commentaires.

2

Je ne sais pas elixir, mais en erlang proprement dit, crypto:hash/2 prend iodata, ce qui n'est pas le cas d'une poignée de fichier. Vous devez lire le fichier et transmettre le contenu à hash(). Si vous connaissez le fichier est assez petit, {ok, Content} = file:read_file("file") (ou l'équivalent élixir) ferait l'affaire.

1

Cela fait aussi le travail:

iex(25)> {:ok, content} = File.read "file" 
{:ok, "Elixir"} 
iex(26)> :crypto.hash(:md5, content) |> Base.encode16 
"A12EB062ECA9D1E6C69FCF8B603787C3" 

Le programme md5sum sur le même fichier retourné:

$ md5sum file 
a12eb062eca9d1e6c69fcf8b603787c3 file 

J'ai utilisé les informations Ryan fournies dans les commentaires ci-dessus, et a ajouté la base. encoder16 pour atteindre le résultat final.