Parcours
/
Elixir
Elixir
/
Exercices
/
Renifleur de fichiers
Renifleur de fichiers

Renifleur de fichiers

Exercice d'apprentissage

Introduction

Binaires

Elixir offre une syntaxe élégante pour manipuler des données binaires, comme on l'a vu avec la forme spéciale <<>> fournie pour travailler avec les bitstrings.

Le type binaire est une spécialisation du type bitstring. Là où un bitstring peut être de n'importe quelle longueur (n'importe quel nombre de bits), un binaire est une donnée dont le nombre de bits est divisible par 8. Autrement dit, quand on travaille avec des binaires, on raisonne souvent en octets (8 bits). Un octet peut représenter des nombres entiers de 0 à 255. Il est courant de manipuler des valeurs d'octets en hexadécimal, 0x00 - 0xFF.

Les littéraux binaires se définissent à l'aide de la forme spéciale <<>>. Pour définir un littéral binaire, on peut utiliser des littéraux entiers et des littéraux string. Les valeurs entières supérieures à 255 débordent et seuls les 8 derniers bits de l'entier sont utilisés. Par défaut, le modificateur ::binary est appliqué à la valeur. On peut concaténer des binaires avec l'opérateur <>/2.

<<255>> == <<0xFF>>
# Overflowing bits are truncated
<<256>> == <<0>>
<<2, 4, 6, 8, 10, 12, 14, 16>> == <<0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C, 0x0E, 0x10>>

Un octet nul est un autre nom pour <<0>>.

Filtrage par motif sur des données binaires

Le filtrage par motif s'étend même aux binaires, et on peut appliquer un motif à une partie des données binaires, un peu comme on le ferait pour une liste.

# Ignore the first 8 bytes, match and bind the remaining to `body`
<<_::binary-size(8), body::binary>>

Comme pour les autres formes de filtrage par motif, on peut s'en servir dans la signature d'une fonction pour choisir parmi plusieurs clauses.

Instructions

Tu travailles sur un projet qui permet aux utilisateurs de téléverser des fichiers sur le serveur pour les partager avec d'autres utilisateurs. On t'a chargé d'écrire une fonction pour vérifier qu'un fichier téléversé correspond à son type de média. Après quelques recherches, tu découvres que les premiers octets d'un fichier sont généralement propres à ce type de fichier, ce qui lui donne une sorte de signature.

Utilise le tableau suivant comme référence :

Type de fichier Extension courante Type de média « signature » binaire
ELF "exe" "application/octet-stream" 0x7F, 0x45, 0x4C, 0x46
BMP "bmp" "image/bmp" 0x42, 0x4D
PNG "png" "image/png" 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A
JPG "jpg" "image/jpg" 0xFF, 0xD8, 0xFF
GIF "gif" "image/gif" 0x47, 0x49, 0x46

1. À partir d'une extension, renvoie le type de média attendu

Implémente la fonction type_from_extension/1. Elle prend une extension de fichier (une string) et renvoie le type de média (string), ou nil si l'extension ne correspond pas à celles attendues.

FileSniffer.type_from_extension("exe")
# => "application/octet-stream"

FileSniffer.type_from_extension("txt")
# => nil

2. À partir d'un fichier binaire, renvoie le type de média attendu

Implémente la fonction type_from_binary/1. Elle prend un fichier (binaire) et renvoie le type de média (string), ou nil si la signature du fichier ne correspond pas à celles attendues.

file = File.read!("application.exe")
FileSniffer.type_from_binary(file)
# => "application/octet-stream"

file = File.read!("example.txt")
FileSniffer.type_from_binary(file)
# => nil

Ne te soucie pas de lire le fichier en binaire. Considère que c'est déjà fait et que les tests te le passent en argument.

3. À partir d'une extension et d'un fichier binaire, vérifie que le fichier correspond au type attendu

Implémente la fonction verify/2. Elle prend un fichier (binaire) et une extension (string), et renvoie un tuple :ok ou :error.

file = File.read!("application.exe")

FileSniffer.verify(file, "exe")
# => {:ok, "application/octet-stream"}

FileSniffer.verify(file, "png")
# => {:error, "Warning, file format and file extension do not match."}
Modifie via GitHub Le lien s'ouvre dans une nouvelle fenêtre ou un nouvel onglet
Elixir Exercism

Prêt à commencer Renifleur de fichiers ?

Inscris-toi sur Exercism pour apprendre et maîtriser Elixir avec 58 concepts168 exercices, et un vrai mentorat humain, le tout gratuitement.