iT邦幫忙

2022 iThome 鐵人賽

DAY 22
0
Software Development

戀戀 Elixir系列 第 22

二十二. Binaries

  • 分享至 

  • xImage
  •  

You have been working on a project which allows users to upload files to the server to be shared with other users.

You have been tasked with writing a function to verify that an upload matches its media type.
You do some research and discover that the first few bytes of a file are generally unique to that file type, giving it a sort of signature.

1. Given an extension, return the expected media type

Implement the type_from_extension/1 function. It should take a file extension (string) and return the media type (string) or nil if the extension does not match with the expected ones.

2. Given a binary file, return the expected media type

Implement the type_from_binary/1 function. It should take a file (binary) and return the media type (string) or nil if the extension does not match with the expected ones.

Don't worry about reading the file as a binary. Assume that has been done for you and is provided by the tests as an argument.

3. Given an extension and a binary file, verify that the file matches the expected type

Implement the verify/2 function. It should take a file (binary) and extension (string) and return an :ok or :error tuple.


https://exercism.org/tracks/elixir/exercises/file-sniffer

defmodule FileSniffer do
  @moduledoc """
  practice binary
  """
  @type_map %{
    "exe" => "application/octet-stream",
    "bmp" => "image/bmp",
    "png" => "image/png",
    "jpg" => "image/jpg",
    "gif" => "image/gif"
  }

  def type_from_extension(extension), do: @type_map[extension]

  def type_from_binary(file_binary) do
    case file_binary do
      <<0x7F, 0x45, 0x4C, 0x46, _::binary>> -> "application/octet-stream"
      <<0x42, 0x4D, _::binary>> -> "image/bmp"
      <<0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A, _::binary>> -> "image/png"
      <<0xFF, 0xD8, 0xFF, _::binary>> -> "image/jpg"
      <<0x47, 0x49, 0x46, _::binary>> -> "image/gif"
      _ -> nil
    end
  end

  def verify(file_binary, extension) do
    type = file_binary |> type_from_binary

    if extension |> type_from_extension === type,
      do: {:ok, type},
      else: {:error, "Warning, file format and file extension do not match."}
  end
end

上一篇
二十ㄧ. Enum
下一篇
二十三. File
系列文
戀戀 Elixir30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言