Zadanie 6

Zadanie 6

(2. skúškové zadanie)

Nezabudnite zadanie nahrať do AIS do príslušného miesta odovzdania (odovzdajte len príslušný zdrojový .c súbor). Súbor je následne nutné v AIS potvrdiť tlačidlom niekoľkokrát za sebou až pokiaľ neuvidíte oznam o úspešnom odovzdaní.

Dôležité informácie

  • Termín odovzdania: Odovzdajte do AIS, 25. máj 2020, 23:59
  • Počet bodov: 10
  • Odovzdávané súbory a formát ich pomenovania (ID nahraďte vašim AIS ID číslom):
    • ID.main.z6.c (celá implementácia zadania spolu s main funkciou)
  • Podmienkou získania bodov za zadanie je, aby bol váš kód kompilovateľný prekladačom gcc s prepínačom -Wall bez chýb a upozornení (teda 0 errors, 0 warnings). Na otestovanie tejto nutnej podmienky máte rôzne možnosti:
  • Nezabudnite dodržať termín odovzdania do AIS, oneskorené odovzdanie nebude akceptované.

Obsah


Príprava

Cieľ zadania

Naprogramujte v jazyku C program na šifrovanie a dešifrovanie textu pomocou stĺpcovej transpozície. Program bude vstupný text získavať zo štandardného vstupu (stdin) a výsledok operácie (šifrovanie alebo dešifrovanie) zapíše v predpísanom tvare na štandardný výstup (stdout). Váš program bude mať formu terminálovej/konzolovej aplikácie, ktorej správanie bude riadené zadanými prepínačmi a argumentami.

Príkaz na spustenie programu

Program sa bude dať spustiť z konzoly pomocou dvoch príkazov, v závislosti od žiadaného operačného režimu (šifrovanie alebo dešifrovanie). Štruktúra oboch príkazov je nasledovná:

Režim šifrovania

./z6 -e key

Režim dešifrovania

./z6 -d key

Popis jednotlivých častí príkazu:

  • -e Povinný prepínač. Určuje, že program vykoná šifrovanie (z angl. encryption)
  • -d Povinný prepínač. Určuje, že program vykoná dešifrovanie (z angl. decryption)
  • key Povinný argument. Predstavuje šifrovací/dešifrovací kľúč (podľa toho aký operačný režim je zvolený). Možnosti zadania kľúča sú opísané v sekcii Možnosti zadania kľúča.

Kedy program končí:

  • ak chýbajú povinné prepínače (-e alebo -d) a ich povinný argument (kľúč) alebo ak prvý argument príkazu nie je -e alebo -d, vtedy program skončí s výpisom textu ERR01.

Hlavné kroky programu

Hlavné kroky fungovania programu sú:

  1. Určenie permutácie P podľa zadaného kľúča (ten je v tvare textového reťazca alebo postupnosti číslic).
  2. Načítanie vstupného textu zo štandardného vstupu.
  3. Šifrovanie alebo dešifrovanie textu pomocou stĺpcovej transpozície (operačný režim je určený prepínačom -e alebo -d). Šifrovanie a dešifrovanie prebehne na základe určenej permutácie P.
  4. Výpis výsledku na štandardný výstup v požadovanom formáte.

Postup

1. Možnosti zadania kľúča

Váš program bude akceptovať dve možnosti zadania kľúča:

  1. Ako textový reťazec.

    Kľúč bude zadaný ako ľubovoľný textový reťazec pozostávajúci len z písmen (použite len malé alebo len veľké písmená). Celý kľúč sa bude nachádzať v jednom prvku poľa argumentov argv.

  2. Ako permutácia čísel 1 až N.

    Kľúč bude zadaný ako ľubovoľná permutácia číslic 1 až N (N predstavuje počet zadaných čísel). Zadaná permutácia musí obsahovať minimálne 2 čísla (kvôli jednoznačnému odlíšeniu od kľúča zadaného vo forme textového reťazca). Musí platiť, že každé číslo 1 až N sa musí v zadanej permutácii vyskytovať práve raz. Každé číslo takto zadaného kľúča sa bude nachádzať v samostatnom prvku poľa argumentov argv. Napríklad pri spustení programu príkazom ./z6 -e 4 2 1 3 5 sa budú čísla kľúča nachádzať v poli argv od prvku argv[2] až po prvok argv[6].

Kedy program končí:

  • ak bol zadaný kľúč vo forme textového reťazca a obsahuje nepovolené znaky, vtedy program skončí s výpisom textu ERR02
  • ak bol zadaný kľúč vo forme postupnosti čísel, ktorá nespĺňa vyššie uvedené požiadavky (t.j. nie je to permutácia čísel 1 až N), vtedy program skončí s výpisom textu ERR03

2. Určenie permutácie pre stĺpcovú transpozíciu

Ak boli korektne zadané všetky požadované prepínače a ich argumenty, program určí permutáciu čísel (pomocou ktorej sa následne vykoná stĺpcová transpozícia), ktorú budeme označovať ako P. Permutácia P sa odvodí zo zadaného kľúča používateľom pri spustení programu. Kvôli názornosti je v nasledujúcom príklade permutácia P vyjadrená pomocou čísel 1 až N. Avšak interne kvôli indexovaniu polí v jazyku C ju odporúčam číslovať od 0 po N-1). Permutácia P by mala byť uložená v poli čísel.

Príklady určenia permutácie P

  • ak bol kľúč zadaný vo forme textového reťazca, permutácia P sa určí na základe poradia písmen v reťazci (t.j. podľa toho v akom poradí idú v abecede)

Príklad textovo zadaného kľúča obsahujúceho reťazec abrakadabra. Pod jednotlivými písmenami kľúča je znázornené korešpondujúce číslo v permutácii P (pri implementácii číslujte od 0).

A  B  R  A  K  A  D  A  B  R  A
1  6 10  2  9  3  8  4  7 11  5

Pri vytváraní permutácie P sa teda najprv číslujú výskyty písmena A, potom B, potom C ... až po písmeno Z. Ak kľúč neobsahuje niektoré písmeno z abecedy, ignoruje sa a ide sa skúmať ďalšie písmeno.

  • ak bol kľúč zadaný vo forme číselnej postupnosti, vtedy je permutácia P určená priamo číslami zadaného kľúča (nezabúdajme, že každá číslica zadaného kľúča je v samostatnom prvku poľa argv).

3. Načítanie vstupného textu

Vstupom do programu je postupnosť znakov ukončená 2 znakmi konca riadku (t.j. prázdnym riadkom).

Pri dešifrovaní

  1. Platné znaky sú len veľké písmená, medzery a konce riadkov, pričom medzery a konce riadkov sa pri načítavaní preskakujú.
  2. Ak sa načíta iný znak ako platný, program skončí s výpisom textu ERR04.

Pri šifrovaní

  1. Každý znak je platný.

  2. Písmená sa pri načítavaní konvertujú na veľké.

  3. Číslice sa prekladajú podľa nasledujúcej konverznej tabuľky

    0: NULA
    1: JEDNA
    2: DVA
    3: TRI
    4: STYRI
    5: PAT
    6: SEST
    7: SEDEM
    8: OSEM
    9: DEVAT

  4. Iné znaky ako číslice a písmená sa pri načítavaní preskakujú.

Príklad načítania vstupného textu pri šifrovaní

Vstupný text: Vitamin D ochrani proti Covid-19.
Výsledný načítaný platný text: VITAMINDOCHRANIPROTICOVIDJEDNADEVAT

Maximálna dĺžka platného textu

Dĺžka výsledného načítaného textu (len platné znaky) nesmie prekročiť limit 1000 znakov (dávajte si pozor na preklad číslic podľa vyššie uvedenej konverznej tabuľky). Ak je tento limit prekročený, program skončí s výpisom textu ERR05.

Nápoveda: Odporúčam použiť načítanie po znakoch, na preklad číslic mať k dispozícii pole reťazcov a tieto pripájať k načítanému reťazcu, napr. pomocou funkcie strcat alebo strcpy. Treba si stále dávať pozor na prekročenie limitu 1000 načítaných platných znakov.

4. Šifrovanie textu

Načítaný platný text sa vloží po riadkoch do tabuľky s N stĺpcami (pripomínam, že N je počet číslic permutácie P). Posledný riadok tabuľky nemusí byť vyplnený úplne. Zápis textu do tabuľky prebieha v smere zhora nadol a zľava doprava. Z takto naplnenej tabuľky získame zašifrovaný text čítaním po stĺpcoch v poradí určenom permutáciou P.

Príklad šifrovania

Načítaný platný vstupný text:

VITAMINDOCHRANIPROTICOVIDJEDNADEVAT

Tabuľka na šifrovanie pomocou stĺpcovej transpozície (v záhlaví tabuľky je uvedená permutácia P, podľa ktorej vykonáme stĺpcovú transpozíciu):

1  6 10  2  9  3  8  4  7 11  5
-------------------------------
V  I  T  A  M  I  N  D  O  C  H  
R  A  N  I  P  R  O  T  I  C  O  
V  I  D  J  E  D  N  A  D  E  V  
A  T

Výsledný zašifrovaný text (získali sme ho čítaním po stĺpcoch v poradí danom permutáciou P):

VRVA AIJ IRD DTA HOV IAIT OID NON MPE TND CCE

Medzery v tomto výpise sú len ilustračné, aby bolo jasne vidieť ako sa čítali jednotlivé stĺpce. Presný formát výpisu je určený ďalej.

5. Dešifrovanie textu

Opäť sa vytvorí tabuľka, do ktorej sa tentokrát vstupný text vkladá po stĺpcoch zhora nadol a v poradí danom permutáciou P. Z takto naplnenej tabuľky získame dešifrovaný text čítaním po riadkoch zhora nadol.

Príklad dešifrovania

Načítaný platný vstupný text (čísla v texte sú len pre ilustráciu):

VRVAAIJIRDDTAHO123

Čiastočne vyplnená tabuľka na dešifrovanie pomocou stĺpcovej transpozície:

1  6 10  2  9  3  8  4  7 11  5
-------------------------------
V  2     A     I     D        H  
R  3     I     R     T        O
V        J     D     A        1   
A

Výsledný dešifrovaný text (získali sme ho čítaním po riadkoch):

V2.A.I.D..HR3.I.R.T..OV..J.D.A..1A.

Znak bodky . v tomto výpise opäť slúži len na ilustráciu. Reálny výstup dešifrovania by bol nasledovný.

  • Vstupný text (zašifrovaný): VRVAAIJIRDDTAHOVIAITOIDNONMPETNDCCE
  • Výstupný text (dešifrovaný): VITAMINDOCHRANIPROTICOVIDJEDNADEVAT

Nápoveda 1: Na riešenie vôbec nepotrebujete 2D pole, stačí vám správne indexovať 1D pole. Ak vám to však uľahčí vyriešenie problému, môžete použiť 2D pole.

Nápoveda 2: Pri riešení si môžete pomôcť konceptom inverznej permutácie, t.j. takého poľa čísel, ktoré hovorí, v ktorom stĺpci tabuľky sa nachádza požadovaný znak zašifrovaného textu (t.j. mapovanie znakov zašifrovaného textu na indexy stĺpcov v tabuľke). Napríklad znak 1 je v stĺpci 0, znak 2 je v stĺpci 3, znak 3 je v stĺpci 5, atď.

6. Formát výstupu

Výsledok šifrovania alebo dešifrovania textu sa vypíše na štandardný výstup v skupinách po 5 znakov.

Príklad

Náš zašifrovaný text by vyzeral nasledovne (z príkladu v časti Šifrovanie):

VRVAA IJIRD DTAHO VIAIT OIDNO NMPET NDCCE

Náš dešifrovaný text by vyzeral nasledovne (z príkladu v časti Dešifrovanie):

VITAM INDOC HRANI PROTI COVID JEDNA DEVAT

Ak dĺžka zašifrovaného/dešifrovaného textu nie je násobkom čísla 5, vtedy bude mať posledná vypísaná skupina menej ako 5 znakov. Ak je násobkom čísla 5, tak za poslednou skupinou nie je medzera.

Po výpise textu program ešte doplní 2 konce riadkov (znak konca riadku je \n), aby sa dal výstup použiť pri opätovnom dešifrovaní alebo šifrovaní.

7. Odporúčané testovanie vášho programu

Aby ste nemuseli počas testovania zadávať dlhé texty manuálne z klávesnice, môžete pri spúštaní programu v konzole využiť presmerovanie štandardného vstupu tak, aby program čítal údaje z textového súboru (znak presmerovania štandardného vstupu je <).

Takisto, ak chcete výsledok šifrovania/dešifrovania presmerovať do súboru, stačí použiť symbol presmerovania štandardného výstupu (znak >).

Postup na overenie funkčnosti vášho programu:

./z6 -e abrakadabra < ot.txt > zt.txt
./z6 -d abrakadabra < zt.txt > ot1.txt
./z6 -d 1 6 10 2 9 3 8 4 7 11 5 < zt.txt > ot2.txt
diff ot1.txt ot2.txt

Súbor ot.txt bude obsahovať ľubovoľný otvorený (nezašifrovaný) text. Súbor zt.txt bude obsahovať text zašifrovaný vašim programom pri použití kľúča abrakadabra. Nakoniec musia byť súbory ot1.txt (výsledok dešifrovania, keď bol kľúč zadaný ako textový reťazec) a ot2.txt (výsledok dešifrovania, keď bol kľúč zadaný ako postupnosť číslic) rovnaké. Program diff vykonáva porovnanie súborov.

Počas testovania si vyskúšajte:

  • rôzne vstupné texty (obsahujúce rôzne platné/neplatné znaky)
  • rôzne kľúče (v tvare textového reťazca alebo číselnej postupnosti)
  • rôzne neplatné situácie (situácie kedy by mal váš program skončiť s výpisom konkrétneho chybového textu)

Ďalšie testovacie príklady

  • Test 1 (všetky súbory v teste 1 na stiahnutie)

    ./z6 -e klucnasifrovanie < ot.txt > zt.txt
    ./z6 -d klucnasifrovanie < zt.txt > ot1.txt
    ./z6 -d 8 9 15 3 10 1 14 6 5 13 12 16 2 11 7 4 < zt.txt > ot2.txt

    Súbory ot1.txt a ot2.txt sa musia po vykonaní príkazov zhodovať.

  • Test 2 (všetky súbory v teste 2 na stiahnutie)

    ./z6 -e 10 11 8 4 12 1 6 9 13 2 7 5 3 < input.txt > fei.txt
    ./z6 -d programovanie < fei.txt > thebest.txt

8. Ukončenie programu

Program/aplikácia skončí v uvedených situáciách (rekapitulácia):

  1. Ak chýbajú povinné prepínače (-e alebo -d) a ich povinný argument (kľúč) alebo ak prvý argument príkazu nie je -e alebo -d, vtedy program skončí s výpisom textu ERR01.
  2. Ak bol zadaný kľúč vo forme textového reťazca a obsahuje nepovolené znaky, vtedy program skončí s výpisom textu ERR02.
  3. Ak bol zadaný kľúč vo forme postupnosti čísel, ktorá nespĺňa uvedené požiadavky (t.j. nie je to permutácia čísel 1 až N), vtedy program skončí s výpisom textu ERR03.
  4. Ak sa pri načítavaní vstupného textu v režime dešifrovania načíta iný znak ako platný, program skončí s výpisom textu ERR04.
  5. Dĺžka načítaného textu (len platné znaky) nesmie prekročiť limit 1000 znakov (dávajte si v režime šifrovania pozor na preklad číslic podľa konverznej tabuľky), ak je tento limit prekročený, program skončí s výpisom textu ERR05.

Testovanie a bodovanie

Zadanie bude hodnotené pomocou automatizovaných testov (otestuje sa séria rôznych vstupných textov, prepínačov a argumentov s rôznymi hodnotami) a preto je potrebné, aby váš program vypisoval na stdout len požadovaný výsledok v požadovanom formáte - žiadne iné znaky, slová, pomocné hlásenia, dekoračné výpisy a pod. (toto bola dosť častá chyba študentov pri zadaní 3,4 a 5). Ak túto podmienku váš program nesplní, je dosť možné, že za zadanie nezískate žiadne body. Preto výrazne odporúčam dôkladne si kontrolovať vaše výstupy/výpisy.

Body sú orientačne rozdelené nasledovne:

  • [2b] Za správne fungovanie šifrovania textu, kde kľúč je zadaný ako textový reťazec.
  • [2b] Za správne fungovanie šifrovania textu, kde kľúč je zadaný ako číselná postupnosť.
  • [2b] Za správne fungovanie dešifrovania textu, kde kľúč je zadaný ako textový reťazec.
  • [2b] Za správne fungovanie dešifrovania textu, kde kľúč je zadaný ako číselná postupnosť.
  • [2b] Za správne ošetrenie chybových situácií (t.j. situácií, kedy by mal program skončiť s príslušným chybovým hlásením, viď. Ukončenie programu)

Poznámka: Nezabudnite, že nutnou podmienkou je, aby bol váš program kompilovateľný prekladačom gcc so zapnutým prepínačom -Wall bez chýb a upozornení (0 errors a 0 warnings). Vo vlastnom záujme si toto otestujte.

Konzultovanie zadania

Všetky vaše otázky smerujúce k zadaniu č.6 môžete zasielať na STUBA e-mailové adresy svojich cvičiacich alebo sa zapojiť do živej diskusie na našom Discord serveri (invite linka bola poslaná cez AIS) v kanáli #zadanie6.

Stay tuned.