exercism/elixir/file-sniffer/lib/file_sniffer.ex

43 lines
1.2 KiB
Elixir

defmodule FileSniffer do
@signatures [
{<<0x7F, 0x45, 0x4C, 0x46>>, "application/octet-stream"},
{<<0x42, 0x4D>>, "image/bmp"},
{<<0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A>>, "image/png"},
{<<0xFF, 0xD8, 0xFF>>, "image/jpg"},
{<<0x47, 0x49, 0x46>>, "image/gif"}
]
@file_types %{
"exe" => "application/octet-stream",
"bmp" => "image/bmp",
"png" => "image/png",
"jpg" => "image/jpg",
"gif" => "image/gif"
}
def type_from_extension(extension), do: @file_types[extension]
def type_from_binary(file_binary) do
Enum.find_value(@signatures, fn {signature, type} ->
with signature_size <- byte_size(signature),
<<file_signature::binary-size(signature_size), _rest::binary>> <- file_binary,
true <- file_signature == signature do
type
else
_ -> nil
end
end)
end
def verify(file_binary, extension) do
ext_type = type_from_extension(extension)
bin_type = type_from_binary(file_binary)
case ext_type == bin_type do
true when ext_type != nil and bin_type != nil ->
{:ok, ext_type}
_ ->
{:error, "Warning, file format and file extension do not match."}
end
end
end