Autorské riešenie
[stiahni spion.py]

  • Počet riešiteľov: 32 / 40 = 80 %

  • Úspešnosť riešenia: 4,61 / 6 = 77 %

Poznáme spôsob ako malí špióni správu zašifrujú: "Zvolia si celé kladné číslo. Správu zapíšu do tabuľky, ktorej počet stĺpcov je rovný zvolenému číslu. Následne správu prečítajú a zapíšu po stĺpcoch, pričom prípadné chýbajúce znaky v poslednom riadku tabuľky doplnia medzerami."

Pre správu "Toto je tajná správa." a číslo 6 to vyzerá nasledovne:

sifrovanie

Text, ktorý sa pôvodne čítal po riadkoch sa prečíta po stĺpcoch:

"Teávo  atts.oap  jr jná "

Ak by sme takýto text zapísali do tabuľky s prehodenými rozmermi:

desifrovanie

a opäť ho prečítali po stĺpcoch, dostali by sme pôvodnú správu:

 "Toto je tajná správa.   "

K pôvodnej správe pribudli nejaké medzery, ale podľa zadania to nie je problém a môžeme ich tam nechať.

Objavili sme dôležitý poznatok: na šifrovanie aj na dešifrovanie môžeme použiť rovnaký postup. Rozdiel bude len v počte stĺpcov tabuľky. Pri šifrovaní je počet stĺpcov daný (v tejto ukážke 6), pri dešifrovaní si ho vieme vypočítať:

dĺžka zašifrovanej správy / počet stĺpcov pri šifrovaní = 24 / 6 = 4

Všimnime si, že pri dešifrovaní už žiadne medzery nie je potrebné dopĺňať.

Ak teda vytvoríme funkciu na šifrovanie, budeme ju môcť použiť aj na dešifrovanie. Musíme však predtým vypočítať počet stĺpcov dešifrovacej tabuľky.

Pre samotné šifrovanie nemusíme vytvárať tabuľku. Tá bola len pomôckou pri ručnom šifrovaní. Všimnime si, že ak budeme text z ukážky čítať:

  • od 0. znaku s krokom 6
  • od 1. znaku s krokom 6
  • ...
  • od (6-1). znaku s krokom 6

sifra bez tabulky

výsledkom bude rovnaký text, ako keď sme ho prečítali z tabuľky po stĺpcoch:

sifra bez tabulky

Funkcia, ktorá zrealizuje takéto čítanie na "preskačku" môže vyzerať nasledovne:

def sifruj(sprava, kluc):
    pocet_stlpcov = kluc
    sifra = ''
    pocet_riadkov = math.ceil(len(sprava) / pocet_stlpcov)
    pocet_medzier = pocet_riadkov * pocet_stlpcov - len(sprava)
    sprava = sprava + ' ' * pocet_medzier
    for index in range(pocet_stlpcov):
        stlpec = sprava[index::pocet_stlpcov]
        sifra = sifra + stlpec
    return sifra

Najskôr vypočítame, akú veľkú tabuľku budeme potrebovať. Počet stĺpcov je zadaný, ostáva teda vypočítať počet riadkov. Tento určíme tak, že vydelíme dĺžku textu počtom stĺpcov a výsledok zaokrúhlime nahor. K textu správy doplníme medzery tak, aby bol vyplnený aj posledný riadok.

Potom postupne zo správy extrahujeme texty, ktoré by v tabuľke boli zapísané v stĺpcoch a spojíme ich.

Všimnime si, že počet stĺpcov sme v hlavičke funkcie pomenovali menom kluc. Pojmom kľúč sa vo všeobecnosti označuje parameter, ktorý by mal byť tajný. Aj keby sme poznali algoritmus, bez znalosti kľúča by sme ho nevedeli správne použiť.

Našou pôvodnou úlohou bolo vytvoriť funkciu pre dešifrovanie. Z úvodnej časti vieme, že dešifrovanie môžeme realizovať rovnakým spôsobom ako šifrovanie. Stačí v tabuľke zameniť počty riadkov a stĺpcov. Funkcia pre dešifrovanie môže vyzerať nasledovne:

def desifruj1(sifra, kluc):
    pocet_stlpcov = len(sifra) // kluc
    return sifruj(sifra, pocet_stlpcov)

Ak by sme neriešili šifrovanie, ale len dešifrovanie, riešenie by mohlo vyzerať nasledovne 

def desifruj(sifra, kluc):
    pocet_stlpcov = len(sifra) // kluc
    sprava = ''
    for index in range(pocet_stlpcov):
        sprava = sprava + sifra[index::pocet_stlpcov]
    return sprava 

Vaše zaujímavé riešenia a najčastejšie chyby

S touto úlohou si väčšina z vás poradila. Len málo z vás malo problém s výpočtom počtu stĺpcov tabuľky na dešifrovanie a "zloženie" pôvodnej správy.

Zbytočnou chybou je aj nerešpektovanie formálnej požiadavky na parametre funkcie (nie globálne premenné) a návratovú hodnotu funkcie (nie výpis výsledku vo funkcii).