Elixir
  • My Elixir journey
  • Why functional programming?
  • Exhort
    • 🗓️Day 22
    • 🗓️Day 21
    • 🗓️Day 20
    • 🗓️Day 19
    • 🗓️Day 18
    • 🗓️Day 17
    • 🗓️Day 16
    • 🗓️Day 15
    • 🗓️Day 14
  • Bits and pieces
    • Clean mix dependencies
    • Run tests automatically on save
    • Run tests and stop on first failure
    • How to remove Tailwind from a Phoenix project
Powered by GitBook
On this page
  • Exercises
  • File Sniffer
  • Overall progress
  1. Exhort

Day 15

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

PreviousDay 16NextDay 14

Last updated 2 years ago

Exercises

File Sniffer

|

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

Notes

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

Overall progress

🗓️
File Sniffer in Elixir on Exercism
View my solution
View gist on GitHub
File Sniffer
An image showing my progress on Exercism. It's 16% as of Monday, 22 August 2022.