🗓️Day 15

Monday, 22 August 2022 - Day 15 of Exhort August 2022 - Exercism (My Elixir Journey)

Exercises

File Sniffer

File Sniffer in Elixir on Exercism | View my solution

Solution

Expand to see code (spoiler alert)
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

View gist on GitHub

Notes

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

Overall progress

Last updated