Autor zadání | Dávid Šutor |
---|---|
Odevzdávané soubory |
main.c
|
Začátek odevzdávání | viz diskusní fórum |
Další odevzdání navíc do | 2025-03-06 24:00 |
Konec odevzdání | 2025-03-12 24:00 |
Vzorová implementace |
/home/kontr/pb071/hw01/hamming
|
Opravy v zadání | 2025-03-04 22:39 |
Predstavenie úlohy
Tvoja mamka prišla za tebou so svojim problémom. Ukázala ti cédéčko, na ktorom má veľmi dôležite dáta, a bojí sa, že sa poškriabaním zničia. Preto ti neostáva nič iné[1], ako napísať vlastné kódovanie schopné odhaliť a opraviť chyby.
Zadanie
Vašou úlohou bude napísať program, ktorý bude vedieť kódovať a dekódovať prúd bajtov zo
štandardného vstupu. Výsledok kódovania, resp. dekódovania sa vypíše na štandardný výstup.
Na kódovanie sa použije naša upravená verzia Hammingovho kódu,
ktorého algoritmus je popísaný v nasledujúcich dvoch sekciách.
Kódovanie
Kódovať budeme každú štvoricu bajtov zo štandardného vstupu na výstupnú päticu bajtov. V rámci tohto textu budeme nazývať túto vstupnú štvoricu informačné slovo a výstupnú päticu bajtov kódové slovo.
Algoritmus si vysvetlíme na príklade kódovania informačného slova $00010203_{\text{HEX}}$ (hodnota pozostáva zo 4 bajtov zapísaných v hexadecimálnej sústave).
Pre lepšiu vizualizáciu slov si každý bajt uložíme do tabuľky pod seba a rozpíšeme na osmicu bitov. Každá bunka tabuľky obsahuje bit a jeho pozíciu. Pozíciu budeme značiť v dvojkovej sústave, kvôli lepšiemu porozumeniu algoritmu.
Pozícia v našom ponímaní neodpovedá skutočnému umiestneniu bitov v informačnom slove. Teda pozícia najmenej významného bitu informačného slova sa nenachádza na pozícii 0 ale na 31. Treba na to myslieť pri implementovaní algoritmu. |
-
Všetky bity informačného slova uložíme do kódového slova, pričom nevypĺňame nultú pozíciu, poslednú pozíciu a pozície, ktoré sú mocninami dvojky. Teda pozície 0, 1, 2, 4, 8, 16, 32 a 39 sa preskočia. Bity začneme ukladať od pozície 3.
-
Nultý a posledný bit kódového slova nastavíme na nulu
-
Bity na pozíciách mocniny dvojky nazveme paritné bity. Hodnota paritného bitu na pozícii
i
-tej mocniny dvojky ($2^i$) sa vypočíta ako bitový exkluzívny súčet (XOR $\oplus$) bitov, ktorých pozícia v dvojkovej sústave má jednotku nai
-tom bite.
Ukážeme si konkrétny výpočet paritného bitu na pozícii 8.
Číslo 8 reprezentujeme v binárnej sústave ako 001000
.
Pre výpočet hodnoty paritného bitu sa musíme pozerať na bity,
ktorých pozícia v binárnej sústave je v tvare XX1XXX
, kde X je buď 0 alebo 1 (viď animácia nižšie).
Výpočet spočíva v tom, že spravíme XOR bitov na pozíciách
XX1XXX
, samozrejme okrem pozície paritného bitu 001000
.
-
$p_{001000} = b_{001001} \oplus b_{001011} \oplus b_{001100} \oplus \cdots \oplus b_{011111} = b_{011100} = 1$ pričom $p_x$ označuje paritný bit na pozícii
x
a $b_x$ označuje bit na pozíciix
.

Takže výsledné kódové slovo bude $2080040806_{\text{HEX}}$.
Dekódovanie
Dekódovanie popíšeme na našom predošlom kódovom slove $2080040806_{\text{HEX}}$. Vzhľadom k tomu, že sme informačné bity pri kódovaní nemodifikovali, tak stačí, aby sme z kódového slova vytiahli informačné slovo presne opačne, ako pri kódovaní. Teda zoberieme prvých 32 bitov, ktoré nie sú na pozíciach mocniny dvojky alebo na nultej a poslednej pozícii. Tým pádom dostaneme naspäť informačné slovo $00010203_{\text{HEX}}$.
Paritné bity využijeme v rámci bonusového rozšírenia.
Okrem papiera a ceruzky si algoritmus môžete vyskúšať v našej interaktívnej aplikácii. Táto aplikácia avšak nepočíta paritné bity, ale umožňuje si ich jednoducho vyklikať. |
Požiadavky
Kostra zadania obsahuje dve prázdne funkcie, encode()
a decode()
.
Vašou úlohou je tieto dve funkcie doimplementovať podľa
nasledujúcich požiadaviek:
bool encode(void);
Funkcia postupne číta bajty zo štandardného vstupu a každé 4 bajty zakóduje na 5 bajtov, ktoré vypíše na štandardný výstup. Použite kódovanie popísané v sekcii Kódovanie.
Ak celkový počet bajtov na vstupe nebude deliteľný 4, tak sa bajty vyplnia nulovými bajtmi sprava. Napríklad vstup $010203_{\text{HEX}}$ sa zakóduje rovnako ako $01020300_{\text{HEX}}$.
Je postačujúce, aby encode()
vrátila vždy true
. Jediný chybový stav je
v prípade, keby nastala chyba pri čítaní zo štandardného vstupu. Tento stav
nemusíte ošetrovať.
bool decode(void);
Analogicky táto funkcia bude čítať bajty zo štandardného vstupu a každých
5 bajtov dekóduje na pôvodné štyri bajty postupom popísaným v sekcii Dekódovanie.
Na rozdiel od encode()
, v prípade, že celkový počet bajtov na vstupe nebude deliteľný 5, tak funkcia
vráti false
a na štandardný chybový výstup vypíše chybovú hlášku "Wrong code word"
a znak konca riadka.
V opačnom prípade vráti true
.
Pre vypísanie hlášky na štandardný chybový výstup použite napríklad príkazfprintf(stderr, "Wrong code word\n") . Znak konca riadka je nutný a testy ho tam budú očakávať.
|
Program berie dva prepínače. -e na kódovanie, ktorý zavolá funkciu encode() a -d na dekódovanie,
ktorý zavolá funkciu decode() .
|
Bonusové rozšírenia
Detekcia a oprava jednoduchej chyby [15 b]
Rozšírte funkciu decode()
aby vo vstupnom kódovom slove vedela na
informačných bitoch rozoznať a opraviť jednoduchú chybu
a na paritných bitoch rozoznať jednoduchú chybu.
Slovo s jednoduchou chybou sa líši od kódového slova práve v jednom bite. |
Algoritmus
-
Urobíme XOR pozícií bitov, ktoré sú nastavené na hodnotu 1.
-
Vetvíme na základe výsledku XORu:
-
Ak výsledok je 0, tak nenastala žiadna chyba.
-
Inak výsledok reprezentuje pozíciu bitu, na ktorom nastala chyba.
-
Príklad
Pre naše príkladové kódové slovo $2080040806_{\text{HEX}}$ spravíme chybu v bite na pozícii 3 a dostaneme slovo $3080040806_{\text{HEX}}$.
Ak spravíme XOR všetkých pozícií bitov s hodnotou 1 tak dostaneme:
Pozície v dvojkovej sústave ktoré XORneme
000010
000011
001000
010101
011100
100101
100110
------
000011
Pri detekcii chyby program vypíše na štandardný
chybový výstup "One-bit error in byte X"
a znak konca riadka, kde X
je poradie
prečítaného bajtu zo vstupu. Indexuje sa od nuly.
V prípade detekcie chyby na informačnom bite sa chyba musí aj opraviť.
Program pokračuje vo výpočte v prípade detekcie chyby.
Požiadavky na návratovú hodnotu decode() zostávajú nezmenené. Z toho vyplýva, že v prípade detekcie chyby bude funkcia aj naďalej vracať true .
|
Užitočné Poznámky
/home/kontr/pb071/hw01/hamming
Ako testovať?
Jednotkové testy
Odporúčaný spôsob, ako otestovať vašu implementáciu, je napísaním jednotkových testov.
V kostre nájdete dve rôzne knižnice na testovanie. Prvej knižnici CUT prislúcha súbor tests-cut/tests-mine.c
a knižnici CLI súbor tests-cli/tests-mine.sh
. Obidva súbory obsahujú podrobný popis, ako si napísať vlastné testy.
Na kompiláciu testov odporúčame použiť cmake. V zložke, v ktorej vám vygeneruje kompilačné súbory, zadajte make hamming-tests-cli
na spustenie CLI
testov. CUT
testy budú skompilované do jedného spustitelného súboru hamming-tests-cut
po zadaní príkazu make
.
Kostra taktiež obsahuje súbor tests-cut/tests-nanecisto.c
, ktorý zodpovedá testom nanečisto, voči ktorým sa bude vyhodnocovať vaše riešenie.
Pri písaní testov sa vám určite bude hodiť naša interaktívna aplikácia.
Príkazový riadok
Ďalší spôsob, ako otestovať vašu implementáciu na Linuxe, je použiť napr. príkaz echo
:
echo -en "\x00\x01\x02\x03" | ./hamming
echo -en "\x20\x80\x04\x08\x06" | ./hamming -d
Keďže nie všetky bajty sú zobraziteľné, je potrebné vedieť výstup
nášho rozumne zobraziť. Našťastie na to môžeme použiť
napr. programy hexdump
alebo xxd
.
echo -en "\x00\x01\x02\x03" | ./hamming | hexdump -C
# Výstup
# 00000000 20 80 04 08 06 | ....|
# 00000005
echo -en "\x20\x80\x04\x08\x06" | ./hamming -d | xxd
# Výstup
# 00000000: 0001 0203 ....
Na Windows odporúčame použiť Windows Subsystem for Linux alebo Git Bash
Niektoré Linuxové distribúcie nepodporujú všetky prepínače. V takom prípade testujte na svoj kód na aise.
Čo znamená príkaz echo -en "\x00\x01\x02\x03" | ./hamming
?
-
spusti príkaz
echo
s prepínačmie
an
s argumentom\x00\x01\x02\x03
.-
prepínač
e
zapína interpretovanie znaku\
-
prepínač
n
vypína pridanie znaku nového riadka na koniec výstupu -
argument
\x00
reprezentuje bajt s hodnotou nula. Hodnota je v šestnástkovej sústave. Analogicky platí pre\x01
,\x02
a\x03
.
-
-
znak
|
spôsobí, že výstup programuecho
sa presmeruje na vstup programu./hamming
.
Opravy v zadání
Extend early deadline by a day
a977860
2025-03-04 22:39
Roman Lacko
-6,3 +6,3 solution-path: "/home/kontr/pb071/hw01/hamming"
publish: now
-deadline-early: 2025-03-05 24:00
+deadline-early: 2025-03-06 24:00
deadline-final: 2025-03-12 24:00