file-sniffer
This commit is contained in:
42
elixir/file-sniffer/lib/file_sniffer.ex
Normal file
42
elixir/file-sniffer/lib/file_sniffer.ex
Normal file
@@ -0,0 +1,42 @@
|
||||
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
|
||||
Reference in New Issue
Block a user