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.

Opgave

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:

Voorbeeld

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'