Michiel Florent van Langren1 (Amsterdam, 1598 – Brussel, 1675), die zijn naam verlatijnste als Michael Florentius Langrenus, was een ingenieur, cartograaf en astronoom die bekendheid verwierf doordat hij de eerste was die een kaart van de maan maakte.
In 1634 beschreef hij een oplossing voor het bepalen van de positie van een schip op zee, meer bepaald de lengtegraad. Om te vermijden dat die vroegtijdig zou uitlekken, gebruikte hij een code die bijna 400 jaar lang niet kon ontcijferd worden. Tot de Belg Jarl Van Eycke in januari 2021 de code eindelijk kon kraken, kort nadat hij samen met een Amerikaan en een Australiër het wereldnieuws haalde met het ontcijferen van de vijftig jaar oude code van de beroemde "Zodiac Killer" seriemoordenaar.
De code van Langrenus maakt gebruik van twee bewerkingen: verstrengelen en ontwarren van een bericht. Beide bewerkingen gebruiken een stapgrootte $$n \in \mathbb{N}_0$$ en heffen elkaar op: als we een bericht verstrengelen met stapgrootte $$n$$ en het resultaat terug ontwarren met dezelfde stapgrootte, dan krijgen we terug het oorspronkelijke bericht. Het omgekeerde geldt ook. We leggen uit hoe deze bewerkingen werken voor stapgrootte $$n=4$$ aan de hand van een bericht dat bestaat uit de letters van het alfabet.
Om een bericht van $$m$$ karakters te verstrengelen, maken we eerst een reeks van $$m$$ lege vakjes. We starten bij het eerste vakje waarin we de eerste letter van het bericht invullen. Daarna springen we telkens $$n$$ vakjes vooruit om de volgende letter van het bericht in te vullen, totdat we voorbij het laatste vakje van de reeks springen. Daarna herhalen we deze procedure door achtereenvolgens te starten bij het tweede vakje, het derde vakje, … en het $$n$$-de vakje, en blijven daarbij steeds de volgende letter van het bericht invullen. Voor de $$m=26$$ letters van het alfabet vullen we eerst van links naar rechts de blauwe de vakjes in, daarna de gele vakjes, de groene vakjes en ten slotte de oranje vakjes.
Om een bericht van $$m$$ karakters te ontwarren, starten we bij de eerste letter van het bericht en springen telkens $$n$$ letters vooruit totdat we voorbij het einde van het bericht springen. Daarna herhalen we deze procedure door achtereenvolgens te starten bij de tweede, de derde, … en de $$n$$-de letter van het bericht. Voor de $$m=26$$ letters van het alfabet lezen we eerst van links naar rechts de blauwe letters uit, daarna de gele letters, de groene letters en ten slotte de oranje letters.
Bij het coderen van een bericht worden eerst alle karakters geschrapt die geen letter zijn. Enkel de letters worden overgehouden en die worden omgezet naar kleine letters. Bovendien worden de eerste negen letters van het alfabet ook nog eens vervangen door een cijfer dat hun positie in het alfabet aangeeft: de letter a staat op positie 1, de letter b op positie 2, … en de letter i op positie 9. Op die manier wordt het bericht
When the sails are strong a ship has no reason to fear turbulence.
bijvoorbeeld eerst omgezet naar
w85nt85s19ls1r5stron71s89p81snor51sonto651rtur2ul5n35
Daarna wordt het bericht verstrengeld. Als we het voorgaande bericht verstrengelen met stapgrootte $$n=3$$ dan krijgen we
won8nt57on16ts588159rspt18u91rls2snu1olrr555ns13ts5ro
Gecodeerde berichten bestaan dus enkel uit cijfers en kleine letters. Om alles nog onleesbaarder te maken, voegt Langrenus op willekeurige plaatsen nog karakters toe die geen cijfers of kleine letters zijn, bijvoorbeeld spaties, hoofdletters of leestekens. Dan wordt het gecodeerde bericht van hierboven bijvoorbeeld verder aangevuld tot
won8ZT MnJWOM Rt5M7o n16ts5 88159r spKVt1 8u91rl s2snAu 1olrr5 55ns13 tsAIJH V5ro
Om een gecodeerd bericht te decoderen, schrappen we eerst alle karakters die geen cijfers of kleine letters zijn. Daarna zetten we de cijfers terug om naar hun corresponderende letter: het cijfer 1 wordt vervangen door de letter a, het cijfer 2 door de letter b, … en het cijfer 9 door de letter i. Het gecodeerd bericht uit bovenstaand voorbeeld wordt dan
wonhntegonaftsehhaeirsptahuiarlsbsnuaolrreeensactsero
Daarna wordt het bericht ontward. Als we bovenstaand bericht ontwarren met stapgrootte $$n=3$$ dan krijgen we terug de opeenvolgende (kleine) letters van het oorspronkelijke bericht:
whenthesailsarestrongashiphasnoreasontofearturbulence
Gevraagd wordt:
Schrijf een functie letter2cijfer waaraan een kleine letter (str) moet doorgegeven worden. Als de letter één van de eerste negen letters van het alfabet is, dan moet de functie het cijfer (str) teruggeven dat correspondeert met de positie van de letter in het alfabet: a staat op positie 1, b op positie 2, enzoverder. Anders moet de functie de letter (str) zelf teruggeven.
Schrijf een functie cijfer2letter waaraan één karakter (str) moet doorgegeven worden. Als het karakter een cijfer is, dan moet de functie de kleine letter (str) teruggeven die op de corresponderende positie in het alfabet staat: op positie 1 staat de letter a, op positie 2 de letter b, enzoverder. Anders moet de functie het karakter (str) zelf teruggeven.
Schrijf een functie ontwarren waaraan een bericht (str) en een stapgrootte $$n \in \mathbb{N}_0$$ (int) moeten doorgegeven worden. De functie moet het resultaat (str) teruggeven dat bekomen wordt door het bericht te ontwarren met stapgrootte $$n$$.
Schrijf een functie decoderen waaraan een bericht (str) moet doorgegeven dat gecodeerd werd met de code van Langrenus. De functie heeft ook nog een tweede optionele parameter stap waaraan de stapgrootte (int; standaardwaarde: 3) van de gebruikte code kan doorgegeven worden. De functie moet de opeenvolgende letters van het originele bericht teruggeven (in kleine letters).
Schrijf een functie verstrengelen waaraan een bericht (str) en een stapgrootte $$n \in \mathbb{N}_0$$ (int) moeten doorgegeven worden. De functie moet het resultaat (str) teruggeven dat bekomen wordt door het bericht te verstrengelen met stapgrootte $$n$$.
Schrijf een functie coderen waaraan een bericht (str) moet doorgegeven. De functie moet het resultaat (str) teruggeven dat bekomen wordt door het bericht te coderen met de code van Langrenus. De codeerstap waarbij na het verstrengelen ook nog willekeurige karakters toegevoegd worden, moet door de functie niet geïmplementeerd worden. De functie heeft ook nog een tweede optionele parameter stap waaraan de stapgrootte (int; standaardwaarde: 3) van de code kan doorgegeven worden.
>>> letter2cijfer('c')
'3'
>>> letter2cijfer('e')
'5'
>>> letter2cijfer('i')
'9'
>>> letter2cijfer('s')
's'
>>> cijfer2letter('3')
'c'
>>> cijfer2letter('5')
'e'
>>> cijfer2letter('9')
'i'
>>> cijfer2letter('s')
's'
>>> ontwarren('abcdefghijklmnopqrstuvwxyz', 3)
'adgjmpsvybehknqtwzcfilorux'
>>> ontwarren('abcdefghijklmnopqrstuvwxyz', 4)
'aeimquybfjnrvzcgkoswdhlptx'
>>> ontwarren('abcdefghijklmnopqrstuvwxyz', 5)
'afkpuzbglqvchmrwdinsxejoty'
>>> decoderen('won8nt57on16ts588159rspt18u91rls2snu1olrr555ns13ts5ro')
'whenthesailsarestrongashiphasnoreasontofearturbulence'
>>> decoderen('won8ZT MnJWOM Rt5M7o n16ts5 88159r spKVt1 8u91rl s2snAu 1olrr5 55ns13 tsAIJH V5ro')
'whenthesailsarestrongashiphasnoreasontofearturbulence'
>>> decoderen('tol2r859 515skr9s n55n5ots 51tot44', stap=5)
'theseadoesnotliketoberestrained'
>>> decoderen('tol2ZTMr JWOMR85M 9515skr9 sn55n5ot KVs51tot 44', 5)
'theseadoesnotliketoberestrained'
>>> verstrengelen('abcdefghijklmnopqrstuvwxyz', 3)
'ajsbktcludmvenwfoxgpyhqzir'
>>> verstrengelen('abcdefghijklmnopqrstuvwxyz', 4)
'ahoubipvcjqwdkrxelsyfmtzgn'
>>> verstrengelen('abcdefghijklmnopqrstuvwxyz', 5)
'aglqvbhmrwcinsxdjotyekpuzf'
>>> coderen('When the sails are strong a ship has no reason to fear turbulence.')
'won8nt57on16ts588159rspt18u91rls2snu1olrr555ns13ts5ro'
>>> coderen('The sea does not like to be restrained.', stap=5)
'tol2r859515skr9sn55n5ots51tot44'