Autorské riešenie
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:
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:
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ť:
výsledkom bude rovnaký text, ako keď sme ho prečítali z tabuľky po stĺpcoch:
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). |
||||||||||
© Univerzita Pavla Jozefa Šafárika v Košiciach, Prírodovedecká fakulta, Ústav informatiky palmaj (zavinac) upjs.sk |