You are on page 1of 6

ZAP Prednášky

Cvičenia
Zadania
Tutoriály a info
SK RU

8. týždeň

Problem Set 5: QR Code

Ciele
1. Porozumieť reprezentácii čísiel v pamäti počítača.
2. Osvojiť si prácu s dvojrozmerným poľom.
3. Vytvoriť vlastné funkcie podľa špecifikácie.
4. Naučiť sa ukončovať funkcie pomocou rozličných návratových hodnôt pri rozličných vstupných parametroch.

QR Code
Pravdepodobne ste sa už stretli s QR kódom. Je to 2D pole určené na vizuálnu reprezentáciu údajov. QR (Quick Response) kód bol
vytvorený v Japonsku v roku 1994 pre automobilový premysel. Neskôr sa rozšíril aj do iných oblastí, vrátane každodenného života.

K získaniu údajov z QR kódu je potrebné použiť skener alebo mať naištalovanú aplikáciu v telefóne, ktorá túto funkcionalitu
zabezpečuje.

V tomto zadaní naštastie nebudeme programovať celú funcionalitu aplikácie, ktorá skenuje QR kód, ale na tomto kóde si ukážeme
základné princípy pre prácu s 2D poľom.

Obr. 1: Ukážka QR kódu, zdroj: https://en.wikipedia.org/wiki/QR_code

QR kód pozostáva z čiernych štvorcov umiestnených v mriežke, ktoré sú na bielom pozadí. To umožnuje čitateľnosť kódu pre
zariadenia ako kamera alebo nejaké špeciálne skenovacie zariadenie. My sa budeme zaujímať najmä o dátovú časť tohto kódu.

Pre uchovanie dát v QR kóde sa používajú štandardné módy, ktoré umožnujú uchovať čísla, alfanumerické znaky, binárne dáta
(bajty), kanji, ale aj iné, ak sú použité rozšírenia.
My budeme pracovať s binárnymi údajmi.

Vašou úlohou je naprogramovať zadanie tak, aby dokázalo konvertovať krátky text do bajtov a tie následne zoskupiť do blokov a
naopak.

Pre kódovanie znakov z reťazca do binárnej sústavy používajte základnú ASCII tabuľku.

Pre uchovávanie bajtov sa budú používať polia typu bool, kde 1 == true a 0 == false.

Bloky sa skladajú z vertikálne uložených bajtov. Bajty sa ukladajú postupne zľava doprava, pokiaľ to šírka bloku dovolí. Až potom sa
ukladajú do nového "riadku". Index nového "riadku" pre blok má offset o veľkosti zodpovedajúcej výške bajtu (8 bitov).

Príklad
Zakódujme si reťazec "Ahoj!". Kódovať je potrebné týchto 6 znakov: 'A', 'h', 'o', 'j', '!', '\0'. Znaky kódujeme do dvojkovej
(binárnej) sústavy na základe ich hodnôt v ASCII tabuľke. Kódujeme aj terminátor, pretože tento znak má tiež svoju hodnotu v ASCII
tabuľke. Hodnoty týchto znakov v ASCII tabuľke sú nasledovné:

ZNAK Hodnota - desiatková sústava Hodnota - dvojková sústava (8 bitov)

'A' 65 01000001

'h' 104 01101000

'o' 111 01101111

'j' 106 01101010

'!' 33 00100001

'\0' 0 00000000
Poznámka: Pod číslom 0 rozumieme hodnotu false a pod číslom 1 rozumieme hodnotu true.

A práve to bude Vašou úlohou: Na základe ASCII hodnoty znaku vypočítať, akú hodnotu má tento znak v dvojkovej sústave. Takto
vznikne byte. Takže ak kódujete skupinu znakov (reťazec), generujete dvojrozmerné pole, v ktorom sa na každom riadku nachádza
jeden byte.

Keď získame skupinu bajtov (viď. tabuľka), môžeme vytvoriť "bloky". Bloky majú definovaný počet stĺpcov aj "riadkov" (offset*8), a je
stanovený tak, aby sa do blokov zmestili všetky znaky. Kódy znakov (bajty) sú do blokov ukladané vertikálne, najskôr zľava doprava,
potom sa podľa offset-u presunieme nižšie a opäť ukladáme bajty vertikálne, zľava doprava. Ak sú k dispozícii bloky navyše,
ukladáme do nich false (kódy znaku '\0').

Keďže počet "riadkov" aj stĺpcov v blokoch je dopredu definovaný, povedzme, že budeme mať 2 "riadky" a 3 stĺpce. Usporiadajme si
znaky nášho reťazca "Ahoj!" v takom poradí, v akom budú ukladané do blokov:

'A' 'h' 'o'


'j' '!' '\0'

Byte každého znaku je uložený vertikálne. Takže pre 2 "riadky" (2*8) a 3 stĺpce bude reťazec "Ahoj!" uložený do blokov nasledovne:

0 0 0
1 1 1
0 1 1
0 0 0
0 1 1
0 0 1
0 0 1
1 0 1

0 0 0
1 0 0
1 1 0
0 0 0
1 0 0
0 0 0
1 0 0
0 1 0

Pre 2 "riadky" a 4 stĺpce bude poradie znakov nasledovné:

'A' 'h' 'o' 'j'


'!' '\0' '\0' '\0'

A v blokoch budú uložené nasledovne:

0 0 0 0
1 1 1 1
0 1 1 1
0 0 0 0
0 1 1 1
0 0 1 0
0 0 1 1
1 0 1 0

0 0 0 0
0 0 0 0
1 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
1 0 0 0

Úloha 1: (De)Kódovanie znaku


Vytvorte funkciu void encode_char(const char character, bool bits[8]) s dvoma parametrami:

const char character - Znak, ktorého ASCII hodnota sa zakóduje z desiatkovej do dvojkovej (binárnej) sústavy
bool bits[8] - Pole hodnôt true alebo false. Jeho veľkosť je 8, lebo každý znak je možné zakódovať na 8 bitov.

Funkcia nevráti žiadnu hodnotu, ale naplní pole bits hodnotami true alebo false. Pole bude obsahovať zápis ASCII hodnoty
znaku character v dvojkovej sústave. Platí, že 1 == true a 0 == false.

Vytvorte funkciu char decode_byte(const bool bits[8]) s parametrom:

const bool bits[8] - Pole hodnôt true alebo false. Jeho veľkosť je 8, lebo každý znak je možné zakódovať na 8 bitov.

Funkcia vráti znak, ktorý je v ASCII tabuľke zapísaný pod rovnakou hodnotou (v desiatkovej sústave), aká je zapísaná v poli bits v
dvojkovej sústave.

Príklad použitia funkcií


p

bool bits1[8];
encode_char('A', bits1);
for(int i = 0; i < 8; i++){
printf("%d", bits1[i]);
}
printf("\n");
// prints: 01000001

bool bits2[8] = {0,1,0,0,0,0,0,1};


printf("%c\n", decode_byte(bits2));
// prints: A

Hodnotenie
Táto úloha je za max. 3 body (každá funkcia je za max. 1.5 bodov).

Úloha 2: (De)Kódovanie reťazca


Vytvorte funkciu void encode_string(const char string[], bool bytes[strlen(string)+1][8]) s dvoma parametrami:

const char string[] - Reťazec, ktorý je potrebné zakódovať na bajty


bool bytes[strlen(string)+1][8] - Dvojrozmerné pole, ktoré na každom riadku obsahuje 1 bajt (8 bitov)

Funkcia nevráti žiadnu hodnotu, ale naplní pole bytes hodnotami true alebo false. Pole bude obsahovať zápis ASCII hodnôt
znakov z reťazca string v dvojkovej sústave vrátane terminátora. Platí, že 1 == true a 0 == false.

Vytvorte funkciu void decode_bytes(const int rows, bool bytes[rows][8], char string[rows]) s troma parametrami:

const int rows - Počet riadkov poľa bytes a počet znakov reťazca string vrátane terminátora
bool bytes[rows][8] - Dvojrozmerné pole, ktoré na každom riadku obsahuje 1 bajt (8 bitov)
char string[rows] - Reťazec, ktorý je potrebné vytvoriť dekódovaním údajov poľa bytes

Funkcia nevráti žiadnu hodnotu, ale naplní reťazec string znakmi dekódovaním údajov v poli bytes. Pole bytes obsahuje na
každom riadku 1 bajt (8 bitov) s hodnotami true alebo false, čo vyjadruje ASCII hodnotu znakov v dvojkovej sústave vrátane
terminátora. Platí, že 1 == true a 0 == false.

Príklad použitia funkcií

char* text = "Hello, how are you?";


const int len = strlen(text);
bool bytes1[len+1][8];
encode_string(text, bytes1);
for(int j = 0; j <= len; j++){
printf("%c: ", text[j]);
for(int i = 0; i < 8; i++){
printf("%d", bytes1[j][i]);
}
printf("\n");
}
// prints:
// H: 01001000
// e: 01100101
// l: 01101100
// l: 01101100
// o: 01101111
// ,: 00101100
// : 00100000
// h: 01101000
// o: 01101111
// w: 01110111
// : 00100000
// a: 01100001
// r: 01110010
// e: 01100101
// : 00100000
// y: 01111001
// o: 01101111
// u: 01110101
// ?: 00111111
// : 00000000

bool bytes2[7][8] = {
{0,1,0,0,1,0,0,0},
{0,1,1,0,0,1,0,1},
{0,1,1,0,1,1,0,0},
{0,1,1,0,1,1,0,0},
{0,1,1,0,1,1,1,1},
{0,0,1,0,0,0,0,1},
{0,0,0,0,0,0,0,0}
};
char string[7];
( )
decode_bytes(7, bytes2, string);

printf("%s\n", string);
// prints: Hello!

Hodnotenie
Táto úloha je za max. 3 body (každá funkcia je za max. 1.5 bodov).

Úloha 3: (De)Kódovanie blokov


Vytvorte funkciu void bytes_to_blocks(const int cols, const int offset, bool blocks[offset*8][cols], const int
rows, bool bytes[rows][8]) s parametrami:

const int cols - Počet stĺpcov pre bloky


const int offset - Počet skupín riadkov pre bloky (upravuje počet riadkov pre bloky)
bool blocks[offset*8][cols] - Dvojrozmerné pole pre bloky s presne definovaným počtom stĺpcov a riadkov
const int rows - Počet riadkov (dĺžka reťazca vrátane terminátora)
bool bytes[rows][8] - Dvojrozmerné pole s bajtami kódov pre znaky reťazca

Funkcia nevráti žiadnu hodnotu, ale naplní pole blocks blokmi bajtov, ktoré obsahujú kódy jednotlivých znakov reťazca. Platí, že 1
== true a 0 == false.

Vytvorte funkciu void blocks_to_bytes(const int cols, const int offset, bool blocks[offset*8][cols], const int
rows, bool bytes[rows][8]) s parametrami:

const int cols - Počet stĺpcov pre bloky


const int offset - Počet skupín riadkov pre bloky (upravuje počet riadkov pre bloky)
bool blocks[offset*8][cols] - Dvojrozmerné pole pre bloky s presne definovaným počtom stĺpcov a riadkov
const int rows - Počet riadkov (dĺžka reťazca vrátane terminátora)
bool bytes[rows][8] - Dvojrozmerné pole s bajtami kódov pre znaky reťazca

Funkcia nevráti žiadnu hodnotu, ale naplní pole bytes kódmi jednotlivých znakov reťazca. Platí, že 1 == true a 0 == false.

Príklad použitia funkcií

int length = 4+1, cols = 3, offset = 2;


bool bytes1[4+1][8] = {
{0,1,0,0,0,0,0,1},
{0,1,1,0,1,0,0,0},
{0,1,1,0,1,1,1,1},
{0,1,1,0,1,0,1,0},
{0,0,0,0,0,0,0,0}
};
bool blocks1[offset*8][cols];
bytes_to_blocks(cols, offset, blocks1, length, bytes1);
for(int j = 0; j < offset*8; j++){
for(int i = 0; i < cols; i++){
printf("%d ", (blocks1[j][i] == true) ? 1 : 0);
}
printf("\n");
if(j % 8 == 7){
printf("\n");
}
}
// prints:
// 0 0 0
// 1 1 1
// 0 1 1
// 0 0 0
// 0 1 1
// 0 0 1
// 0 0 1
// 1 0 1
//
// 0 0 0
// 1 0 0
// 1 0 0
// 0 0 0
// 1 0 0
// 0 0 0
// 1 0 0
// 0 0 0

bool blocks2[2*8][3] = {
{0,0,0},
{1,1,1},
{0,1,1},
{0,0,0},
{0,1,1},
{0,0,1},
{0,0,1},
{1,0,1},
{ }
{0,0,0},
{1,0,0},
{1,0,0},
{0,0,0},
{1,0,0},
{0,0,0},
{1,0,0},
{0,0,0}
};
bool bytes2[length][8];
blocks_to_bytes(3, 2, blocks2, length, bytes2);
for(int j = 0; j < length; j++){
for(int i = 0; i < 8; i++){
printf("%d", bytes2[j][i]);
}
printf("\n");
}
// prints:
// 01000001
// 01101000
// 01101111
// 01101010
// 00000000

Hodnotenie
Táto úloha je za max. 5 bodov (každá funkcia je za max. 2.5 bodov).

Požiadavky pre úspešné odovzdanie zadania


Projekt musí byť odovzdaný včas v git repozitári na adrese git.kpi.fei.tuke.sk (viď nižšie).
Počas prekladu nemôže dôjsť ku žiadnej chybe! Projekt sa bude prekladať prekladačom gcc pomocou nasledovných
prepínačov:

gcc -std=c11 -Werror -Wall -lm

Vo výslednej implementácii sa nemôže nachádzať žiadna globálna premenná.

Odovzdávanie projektu
Zadanie odovzdajte do 26.11.2021 (piatok). Posledné testovanie prebehne v tento deň o polnoci.

Zadanie sa odovzdáva prostredníctvom systému na správu verzií Git na serveri git.kpi.fei.tuke.sk.

Názov Vášho projektu musí byť v tvare: zap-2021-id.

Projekt musí mať nasledujúcu štruktúru priečinkov a súborov:

.
├── ps5

│   └── qr.c

└── README

Význam jednotlivých súborov je nasledovný:

README - Súbor, v ktorom bude uvedená Vaša skupina, ktorú navštevujete na cvičeniach:

GROUP : C1

/ps5/qr.c - Zdrojový kód pre riešenia úloh 1-3

Upozornenie: Je dôležité, aby Vaše súbory zachovali uvedenú štruktúru. Ak sa niektorý zo súborov síce v repozitári nachádza,
ale v inom priečinku, bude to považované za chybu a takýto projekt nebude považovaný za správny.

Upozornenie: Pri názvoch priečinkov, súborov a obsahu súboru README záleží na veľkosti písmen!

Poznámka: Ak sa vo Vašom projekte budú nachádzať ďalšie súbory okrem požadovaných, ich existencia nebude považovaná za
chybu.

Hodnotenie a testovanie
Za zadanie môžete získať max. 11 bodov, z toho max. 3 body za úlohy č. 1 a 2, a max. 5 bodov za úlohu č. 3. Ľubovoľné 3 body sa
započítajú do zápočtu, ostatné body sa započítajú do skúšky. Počet získaných bodov sa bude odrážať od výsledku testov, ktorými
Vaše zadanie úspešne prejde. Overovať sa bude:
Štruktúra Vášho projektu (či sa v ňom nachádzajú všetky potrebné súbory).
Funkčnosť Vašej implementácie.

Váš kód sa bude prekladať prekladačom gcc s nasledovnými prepínačmi:

gcc -std=c11 -Werror -Wall -lm

Za chybu sa bude považovať:

Ak vo Vašej implementácii použijete globálnu premennú.


Ak počas prekladu dôjde ku chybe (upozornenia sú priamo konvertované na chyby).
Ak Vaša implementácia neprejde niektorým z testov.

Testovanie Vašich riešení sa bude vykonávať automaticky každé 3 hodiny a to konkrétne o 0300, 0600, 0900, 1200, 1500, 1800, 2100 a
2400.

Vaše riešenia prejdú kontrolou originality. Preto sa pri práci na Vašom zadaní správajte podľa pravidiel
etického kódexu! V prípade,
že odovzdáte zadanie, ktoré nie je Vaše, môžete byť vylúčení z predmetu!

© Copyright 2021 KPI FEI TUKE.

Poháňané CSS rámcom Bootstrap v4

You might also like