> For the complete documentation index, see [llms.txt](https://elixir.petrolidas.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://elixir.petrolidas.com/exhort/day-15.md).

# Day 15

## Exercises

* [x] [File Sniffer](#file-sniffer)

### File Sniffer

[File Sniffer in Elixir on Exercism](https://exercism.org/tracks/elixir/exercises/file-sniffer) **|** [View my solution](https://exercism.org/tracks/elixir/exercises/file-sniffer/solutions/petros)

#### Solution

<details>

<summary>Expand to see code (spoiler alert)</summary>

{% code lineNumbers="true" %}

```elixir
defmodule FileSniffer do
  @exe_media_type "application/octet-stream"
  @bmp_media_type "image/bmp"
  @png_media_type "image/png"
  @jpg_media_type "image/jpg"
  @gif_media_type "image/gif"

  @spec type_from_extension(String.t()) :: String.t()
  def type_from_extension("exe"), do: @exe_media_type
  def type_from_extension("bmp"), do: @bmp_media_type
  def type_from_extension("png"), do: @png_media_type
  def type_from_extension("jpg"), do: @jpg_media_type
  def type_from_extension("gif"), do: @gif_media_type

  @exe_signature <<0x7F, 0x45, 0x4C, 0x46>>
  @bmp_signature <<0x42, 0x4D>>
  @png_signature <<0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A>>
  @jpg_signature <<0xFF, 0xD8, 0xFF>>
  @gif_signature <<0x47, 0x49, 0x46>>

  @spec type_from_binary(binary()) :: String.t()
  def type_from_binary(<<@exe_signature, _::binary>>), do: @exe_media_type
  def type_from_binary(<<@bmp_signature, _::binary>>), do: @bmp_media_type
  def type_from_binary(<<@png_signature, _::binary>>), do: @png_media_type
  def type_from_binary(<<@jpg_signature, _::binary>>), do: @jpg_media_type
  def type_from_binary(<<@gif_signature, _::binary>>), do: @gif_media_type

  @spec verify(binary(), String.t()) :: {:ok | :error, String.t()}
  def verify(file_binary, extension) do
    media_type = type_from_extension(extension)

    cond do
      type_from_binary(file_binary) == media_type ->
        {:ok, media_type}

      true ->
        {:error, "Warning, file format and file extension do not match."}
    end
  end
end

```

{% endcode %}

[View gist on GitHub](https://gist.github.com/petros/298441d6c37bb32a7ab9e77ecda149e3)

</details>

#### Notes

This one was not very difficult. I like how I used module attributes to avoid repeating myself with the media type.

## Overall progress

<figure><img src="/files/SEikvRb616Seo1qGJUc8" alt="An image showing my progress on Exercism. It&#x27;s 16% as of Monday, 22 August 2022."><figcaption></figcaption></figure>
