Autoři zadání | Petr Pilař Tobiáš Kamenický |
---|---|
Úprava | Patrick Ondika |
Odevzdávané soubory |
ascii85.c
|
Začátek odevzdávání | viz diskusní fórum |
Další odevzdání navíc do | 2024-03-07 12:00 |
Konec odevzdání | 2024-03-13 24:00 |
Vzorová implementace |
/home/kontr/pb071/hw01/ascii85
|
Opravy v zadání | 2024-03-06 13:34 3 |
Představení úkolu
Ascii85 (někdy též nazývané Base85) je kódování, které bylo vytvořeno primárně za účelem konverze binárních dat na data textová. Tato konverze umožňuje jejich přenos přes výhradně textové protokoly. Jelikož některé protokoly umožňují používání pouze vybraných tisknutelných znaků, je rozsah výstupních symbolů kódování Ascii85 omezen.
Zadání
Vaším úkolem bude vytvořit program schopný kódovat a dekódovat data ze standardního vstupu pomocí algoritmu Ascii85.
Ascii85 každým 4 bajtům přiřadí bajtů 5. Postup je následující: Vstupní 4 bajty převedeme na jedno číslo N (tak, že ony 4 bajty „poskládáme za sebe“). Z tohoto čísla N nejprve vezmeme zbytek po dělení 85, čímž získáme náš první mezivýpočet, poté se N celočíselně vydělí 85 (tento proces se celkem opakuje pětkrát, čímž získáme 5 čísel). Ke každému takto získanému číslu přičteme 33. Tím jsme získali ASCII kódy výsledných pěti znaků.
Zamyslete se nad tím, které numerické typy mají dostatečný rozsah — zaručují vám, že se do nich každé vstupní číslo N vejde.
|
Příklad
Vstup: "Lore"
Vstupní bajt | Dekadické vyjádření | Binární vyjádření |
---|---|---|
L |
76 |
01001100 |
o |
111 |
01101111 |
r |
114 |
01110010 |
e |
101 |
01100101 |
N
je tedy v binární soustavě vyjádřeno jako 01001100011011110111001001100101
, v dekadické je to 1282372197
.
Zbytek po dělení 85 | Výsledek dělení 85 |
---|---|
62 |
15086731 |
81 |
177490 |
10 |
2088 |
48 |
24 |
24 |
0 |
Výsledkem tedy bude 5 bajtů vyjádřených znaky s ASCII označením 95, 114, 43, 81, 57 což jsou znaky '_'
, 'r'
, '+'
, 'Q'
, '9'
.
Výstup: "_r+Q9"
Požadavky
Váš program musí jít přeložit a fungovat dle požadavků pro zkompilování na Aise.
Kódování
Funkce int encode(void)
zakóduje data načtená ze standardního vstupu pomocí Ascii85 a vypíše je na standardní výstup.
-
Ze standardního vstupu přestaňte číst, jakmile funkce pro čtení signalizuje konec vstupu hodnotou
EOF
(End of File). -
Pokud vstup skončí, aniž by z něj program načetl kompletní čtveřici bajtů, doplňte ji zprava znaky
'\0'
. -
Dojde-li k chybě, funkce vrátí nenulové kladné číslo, jinak vrátí
0
. -
Funkce musí na konec výstupu zapsat znak nového řádku,
'\n'
.
Funkce encode() vrací hodnotu typu int především kvůli konzistenci s funkcí decode() (viz níže). Jestliže nebudete pracovat s žádnými zdroji, encode() by měla vždy vracet 0 .
|
Dekódování
Funkce int decode(void)
dekóduje data načtená ze standardního vstupu, která byla zakódována pomocí Ascii85, a vypíše je na standardní výstup.
-
Ze standardního vstupu přestaňte číst, jakmile funkce pro čtení signalizuje konec vstupu hodnotou
EOF
(End of File). -
Při dekódování neodstraňujte z konce výstupu znaky
'\0'
. Nemůžete vědět, jestli původní vstup končil znaky'\0'
, jestli byly doplněny při zakódování, nebo jestli je vstupem např. obrázek ve formátu PNG, kde se nulové bajty běžně vyskytují. -
Funkce musí při čtení ignorovat bílé znaky (např.
'\n'
). -
Pokud načtený vstup nemohl vzniknout použitím Ascii85, tedy:
-
jeho délka není dělitelná pěti,
-
obsahuje bajty, které Ascii85 nevyužívá a které nejsou bílé, nebo
-
celková hodnota po dekódování přesahuje 4 bajty;
funkce vrátí nenulové kladné číslo, jinak vrátí
0
.
-
Kostra řešení je navržena tak, že funkce encode() je volána z funkce main() , jestliže je program spuštěn bez přepínačů, nebo právě s přepínačem -e .
Podobně, decode() je z main() volána, pokud je program spuštěn právě s přepínačem -d .
|
Příklady
Poznámky
-
Pro čtení doporučujeme použít bezparametrickou funkci
getchar(3)
. Tato funkce vrací buď jeden znak ze standardního vstupu, neboEOF
, pokud už žádné další znaky není možné přečíst. Návratovým typem této funkce jeint
, aby bylo možné rozlišitEOF
od vstupních bajtů. -
Zda je znak bílý, lze ověřit pomocí funkce
isspace(3)
. -
Při zadávání vstupu z příkazové řádky můžete poslat znak EOF stisknutím
^D
(Ctrl+D), čímž značíme konec vstupu. -
Pro testování vaší implementace můžete na Linuxu použít např. příkaz
echo -en 'Donec nec euismod orci' | ./ascii85
Na Windows doporučujeme použít Windows Subsystem for Linux nebo Git Bash.
-
Pro dekódování může být užitečné umět přečíst netisknutelné znaky. To můžete v Linuxovém terminálu udělat např. pomocí
hexdump
.-
Příklad: Chceme-li se podívat, zda nám sekvence encode a decode vrátí původní sekvenci bajtů, uděláme to následovně:
echo -en "\x00\x01\x02\x03" | ./ascii85 -e | ./ascii85 -d | hexdump -c
Výstupem bude sekvence bajtů oddělených mezerami, kde první sloupec značí počáteční pozici.
0000000 \0 001 002 003 0000004
-
-
Kontrola bude probíhat porovnáváním výstupů. Dejte si tedy pozor, ať nevypisujete nic navíc.
-
V případě chybných vstupů není kontrolován standardní výstup programu, ale pouze, zda funkce
encode
(resp.decode
) vrací nenulové kladné číslo. -
Na standardní chybový výstup nic nevypisujte. O to se postará funkce
main
z kostry. Tuto funkci neupravujte.
-
-
Své vypracování můžete porovnat se vzorovým, které naleznete na aise. Umístění vzoru je následující:
/home/kontr/pb071/hw01/ascii85
-
Pro testování doporučujeme použít buď CUT nebo CLI testy. CUT je vhodný na testování malých komponent, zatímco CLI je vhodnější na testování celkového fungování programu, a bude se spouštět při commitu na git. První úloha je dostatečně malá na to, aby dávaly smysl obě možnosti.
Opravy v zadání
Extend early deadline
c4e60e9
2024-03-06 13:34
Roman Lacko
-7,3 +7,3 publish: now
publish-solution: ~
-deadline-early: 2024-03-06 24:00
+deadline-early: 2024-03-07 12:00
deadline-final: 2024-03-13 24:00
Fix shell command
e9db2e3
2024-03-03 09:35
Filip Krása
-148,3 +148,3 nebo link:https://www.fi.muni.cz/pb071/man/#git-for-windows-verzovac%C3%AD-syst%
----
-echo -en "\x00\x01\x02\x03" | | ./ascii85 -e | ./ascii85 -d | hexdump -c
+echo -en "\x00\x01\x02\x03" | ./ascii85 -e | ./ascii85 -d | hexdump -c
----
Fix example output
78bd79a
2024-02-29 10:56
xondika
-101,3 +101,3 Podobně, `decode()` je z `main()` volána, pokud je program spuštěn právě s
| Vstup | Výstup
-| `Man` | `9jqo>`
+| `Man` | `>oqj9`
| `Donec nec euismod orci` | `SsQu6#Z#j@*?#j@0-elB2f>0ACobq@`