Morbit is een geheimschrift waarvan de naam een samentrekking is van MORse en BIT. Dit doet al vermoeden dat het coderen van berichten in twee stappen gebeurt.
Eerst wordt een bericht omgezet naar morse: een code die gebruikt werd om berichten via een telegraaf te versturen. Een bericht in morse bestaat uit een opeenvolging van korte signalen (voorgesteld door een punt (.)) en lange signalen (voorgesteld door een streep (-)). Elk karakter in het bericht wordt in morse voorgesteld als een unieke combinatie van korte en lange signalen: de letter S wordt bijvoorbeeld voorgesteld door drie korte signalen (...) en de letter O door drie lange signalen (---). Tussen het versturen van twee opeenvolgende karakters wordt telkens een korte pauze ingelast, die voorgesteld wordt door een kleine letter x. Tussen het versturen van twee opeenvolgende woorden wordt telkens een langere pauze ingelast, die voorgesteld wordt door xx (twee keer de kleine letter x). Op die manier wordt het bericht SOS SOS in morse voorgesteld als
...x---x...xx...x---x...
Bij morse wordt de term bit gebruikt voor één enkel karakter dat de duur van een signaal voorstelt: een punt (.), een streep (-) of een pauze (x).
Voor de tweede codeerstap verdelen we de morsevoorstelling in groepen van twee opeenvolgende bits
.. .x -- -x .. .x x. .. x- -- x. ..
Als de morsevoorstelling bestaat uit een oneven aantal bits, dan wordt er achteraan nog een kleine letter x toegevoegd. Daarna vervangen we elke groep van twee bits door een cijfer (1 tot en met 9; geen 0) op basis van een sleutelwoord met 9 letters. Het sleutelwoord MORSE CODE wordt bijvoorbeeld geassocieerd met het numeriek sleutelwoord 568931724 (een permutatie van de cijfers 1 tot en met 9) door de letters van het sleutelwoord in alfabetische volgorde te zetten (CDEEMOORS) en in die volgorde te koppelen aan de opeenvolgende cijfers (123456789)
sleutelwoord | M | O | R | S | E | C | O | D | E |
numerieke sleutel | 5 | 6 | 8 | 9 | 3 | 1 | 7 | 2 | 4 |
eerste bit | . | . | . | - | - | - | x | x | x |
tweede bit | . | - | x | . | - | x | . | - | x |
Als dezelfde letter meerdere keren voorkomt in het sleutelwoord (zoals de letter O en de letter E in bovenstaand voorbeeld), dan worden de voorkomens van links naar rechts gekoppeld aan oplopende cijfers. De letters van het sleutelwoord worden ook gekoppeld aan een unieke combinatie van twee bits, die altijd in de vaste volgorde staan zoals aangegeven in bovenstaande tabel. Uit de tabel kunnen we dan bijvoorbeeld afleiden dat de bits .. corresponderen met het cijfer 5, de bits .x met het cijfer 8 en de bits -- met het cijfer 3. Het bericht SOS SOS wordt in morbit met sleutelwoord MORSE CODE dus gecodeerd als
583158752375
Bij het decoderen van een cijfertekst die met morbit gecodeerd werd, gaan we omgekeerd te werk. Eerst wordt elk cijfer uit de cijfertekst omgezet naar het corresponderende paar van twee bits. Dit levert een bericht in morse op, dat terug kan omgezet worden naar klare tekst.
We leggen een morsecode vast in een tekstbestand. Elke regel van het bestand bevat een uniek karakter, gevolgd door een tab en de unieke combinatie van punten (.) en strepen (-) waardoor het karakter voorgesteld wordt in morse. Dit zijn bijvoorbeeld enkele regels uit zo'n bestand met een morsecode (morse.txt1):
A .- B -... C -.-. D -.. E . ⋮ ⋮ ( -.--. = -...- @ .--.-.
Definieer een klasse Morbit om codecs voor te stellen waarmee berichten kunnen gecodeerd en gedecodeerd worden volgens morbit met een gegeven sleutelwoord. Bij het aanmaken van een codec (Morbit) moeten twee argumenten doorgegeven worden: i) een sleutelwoord $$s$$ (str) dat bestaat uit 9 letters en ii) de locatie (str) van een bestand met een morsecode $$\mathcal{M}$$. Karakters in het sleutelwoord die geen letter zijn moeten genegeerd worden en bij het verwerken van sleutelwoorden mag geen onderscheid gemaakt worden tussen hoofdletters en kleine letters. Na het aanmaken moet elke codec (Morbit) een eigenschap numerieke_sleutel hebben die verwijst naar de numerieke sleutel (str) van de codec. Daarnaast moeten op een codec (Morbit) minstens de volgende methoden kunnen aangeroepen worden:
Een methode morse2cijfer waaraan een string (str) moet doorgegeven worden met een combinatie van twee bits (in morse). De functie moet het cijfer (str) teruggeven dat op basis van sleutelwoord $$s$$ correspondeert met de gegeven combinatie van bits.
Een methode cijfer2morse waaraan een cijfer (str) tussen 1 en 9 (grenzen inbegrepen) moet doorgegeven worden. De functie moet de combinatie van twee bits (str) teruggeven die op basis van sleutelwoord $$s$$ correspondeert met het gegeven cijfer.
Een methode tekst2morse waaraan een bericht in klare tekst (str) moet doorgegeven worden. De functie moet het bericht in morse (str) teruggeven, waarbij de omzetting gebeurt volgens code $$\mathcal{M}$$. Eén of meer opeenvolgende karakters van het bericht die niet voorkomen in code $$\mathcal{M}$$ vormen samen één woordscheidingsteken in het bericht (een plaats waar twee opeenvolgende woorden van elkaar gescheiden worden).
Een methode morse2tekst waaraan een bericht in morse (str) moet doorgegeven worden, waarbij de omzetting naar morse gebeurd is volgens code $$\mathcal{M}$$. De functie moet het bericht in klare tekst (str) teruggeven. Daarbij wordt elk woordscheidingsteken in morse (xx) in klare tekst omgezet naar een spatie.
Een methode codeer waaraan een bericht in klare tekst (str) moet doorgegeven worden. De functie moet de cijfertekst (str) teruggeven na codering van de klare tekst in morbit met sleutelwoord $$s$$, waarbij de omzetting naar morse gebeurt volgens code $$\mathcal{M}$$.
Een methode decodeer waaraan een cijfertekst (str) moet doorgegegeven worden die gecodeerd werd naar morbit met sleutelwoord $$s$$, en waarbij de omzetting naar morse gebeurd is volgens code $$\mathcal{M}$$. De functie moet het bericht (str) in klare tekst teruggeven.
In onderstaande voorbeeldsessie gaan we ervan uit dat het tekstbestand morse.txt2 zich in de huidige directory bevindt.
>>> codec = Morbit('MORSE CODE', 'morse.txt3')
>>> codec.numerieke_sleutel
'568931724'
>>> codec.morse2cijfer('..')
'5'
>>> codec.morse2cijfer('.x')
'8'
>>> codec.morse2cijfer('--')
'3'
>>> codec.cijfer2morse('5')
'..'
>>> codec.cijfer2morse('8')
'.x'
>>> codec.cijfer2morse('3')
'--'
>>> codec.tekst2morse('SOS SOS')
'...x---x...xx...x---x...'
>>> codec.morse2tekst('...x---x...xx...x---x...')
'SOS SOS'
>>> codec.codeer('SOS SOS')
'583158752375'
>>> codec.decodeer('583158752375')
'SOS SOS'