Az Elixir elegáns szintaxist kínál a bináris adatokkal való munkához, ahogy azt a bitstringek kezelésére szolgáló <<>> speciális formánál is láttuk.
A bináris típus a bitstring típus egy specializációja. Míg a bitstringek tetszőleges hosszúságúak lehetnek (bármennyi bitből állhatnak), addig a binárisoknál a bitek száma osztható 8-cal. Vagyis amikor binárisokkal dolgozunk, gyakran bájtokban (8 bitben) gondolkodunk. Egy bájt 0 és 255 közötti egész számokat képes ábrázolni. A bájtértékekkel gyakran hexadecimális formában dolgozunk, 0x00 - 0xFF.
A bináris literálokat a <<>> bitstring speciális formával definiáljuk. Bináris literál definiálásakor egész számokat és string literálokat használhatunk. A 255-nél nagyobb egész értékek túlcsordulnak, és csak az egész szám utolsó 8 bitje lesz felhasználva. Alapértelmezés szerint a ::binary módosító kerül az értékre. A binárisokat a <>/2 operátorral fűzhetjük össze.
<<255>> == <<0xFF>>
# Overflowing bits are truncated
<<256>> == <<0>>
<<2, 4, 6, 8, 10, 12, 14, 16>> == <<0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C, 0x0E, 0x10>>
A null bájt a <<0>> másik neve.
A mintázatillesztés a binárisokra is kiterjed, és a bináris adatok egy részére ugyanúgy illeszthetünk mintázatot, mint egy listára.
# Ignore the first 8 bytes, match and bind the remaining to `body`
<<_::binary-size(8), body::binary>>
A mintázatillesztés más fajtáinál megszokott módon ezt függvényszignatúrákban is használhatjuk, amikor több függvényklóz közül kell választani.
Egy olyan projekten dolgoztál, amely lehetővé teszi a felhasználóknak, hogy fájlokat töltsenek fel a szerverre, hogy más felhasználókkal megosszák azokat. Az a feladatod, hogy írj egy függvényt, amely ellenőrzi, hogy a feltöltött fájl megfelel-e a médiatípusának. Utánanézel a dolgoknak, és rájössz, hogy egy fájl első néhány bájtja általában az adott fájltípusra jellemző, afféle aláírást adva neki.
Használd az alábbi táblázatot referenciaként:
| Fájltípus | Gyakori kiterjesztés | Médiatípus | bináris „aláírás” |
|---|---|---|---|
| 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 |
Valósítsd meg a type_from_extension/1 függvényt. Bemenetként egy fájlkiterjesztést (string) vesz át, és visszaadja a médiatípust (string), vagy nil-t, ha a kiterjesztés nem egyezik a vártak egyikével sem.
FileSniffer.type_from_extension("exe")
# => "application/octet-stream"
FileSniffer.type_from_extension("txt")
# => nil
Valósítsd meg a type_from_binary/1 függvényt. Bemenetként egy fájlt (binary) vesz át, és visszaadja a médiatípust (string), vagy nil-t, ha a fájl aláírása nem egyezik a vártak egyikével sem.
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 foglalkozz azzal, hogy binárisként olvasd be a fájlt. Tekintsd úgy, hogy ezt már megtették helyetted, és a tesztek argumentumként adják át.
Valósítsd meg a verify/2 függvényt. Bemenetként egy fájlt (binary) és egy kiterjesztést (string) vesz át, és egy :ok vagy :error tuple-t ad vissza.
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."}
Iratkozz fel az Exercism-re, hogy megtanuld és elsajátítsd a(z) Elixir nyelvet 58 fogalom168 feladat segítségével, valódi emberi mentorálással, mindez ingyen.