De term cryptex is een neologisme dat Dan Brown1 bedacht voor zijn roman De Da Vinci Code2 uit 2003, en duidt op een draagbare kluis die gebruikt wordt om geheime berichten te verbergen. Het is een samentrekking van het Griekse woord κρυπτός (kryptós, "verborgen, geheim") en het Latijnse woord codex.

cryptex
Replica van de cryptex uit het boek De Da Vinci Code (2003) van Dan Brown. Deze cryptex bestaat uit vijf schijven waarop telkens alle letters van het alfabet voorkomen.

Een cryptex bestaat uit $$n$$ schijven die onafhankelijk van elkaar kunnen roteren. Rondom elke schijf staan $$m$$ verschillende karakters (zowel letters, cijfers, witruimtekarakters als leestekens zijn toegelaten). Daardoor kan een cryptex op $$m^n$$ verschillende combinaties ingesteld worden. Een cryptex verschilt van een traditioneel cijferslot door het feit dat er ook letters op de schijven kunnen staan, in plaats van enkel cijfers. Daardoor kan de combinatie waarmee de cryptex ontgrendeld wordt een woord of een naam zijn — net zoals een wachtwoord  — wat mogelijks makkelijker te onthouden is dan een reeks cijfers.

  schijf 0 schijf 1 schijf 2 schijf 3 schijf 4
ring 0 A A A A A
ring 1 D E E C D
ring 2 E I I D E
ring 3 G L L E  
ring 4 H N N K H
ring 5 L O O L K
ring 6 M P R N R
ring 7 R R S R S
ring 8 S T T S T
ring 9 W U U T Y

Hierboven staat bijvoorbeeld een cryptex die bestaat uit 5 schijven en met 10 karakters op elke schijf. Merk op dat er naast hoofdletters ook één spatie voorkomt op de laatste schijf, waardoor zowel vier- als vijfletterwoorden kunnen gevormd worden. Er kunnen met deze cryptex in totaal zo'n 2.000 woorden gevormd worden, waarbij zelfs nog niet eens rekening wordt gehouden met quasi-woorden (BLATS of WOOT), eigennamen (DILAN of MOSES), afkortingen, anderstalige woorden of onbestaande woorden die enkel gekend zijn door de eigenaar van de cryptex.

Een combinatie van $$n$$ letters die naast elkaar staan op een cryptex noemen we een ring. In totaal heeft een cryptex $$m$$ ringen die we indexeren vanaf nul. Om na te gaan of de cryptex ontgrendeld is, wordt per definitie de combinatie op ring 0 gecontroleerd.

Opgave

De configuratie van een cryptex met $$n$$ schijven en $$m$$ ringen wordt omschreven in een tekstbestand dat bestaat uit $$n$$ regels. Deze regels beschrijven de opeenvolgende schijven en bevatten elk de $$m$$ karakters op een schijf. Opeenvolgende karakters in de omschrijving van een schijf staan initieel op ringen $$0, 1, \ldots, m - 1$$ van de cryptex. De cryptex uit de inleiding wordt dan bijvoorbeeld als volgt omschreven:

ADEGHLMRSW
AEILNOPRTU
AEILNORSTU
ACDEKLNRST
ADE HKRSTY

Merk op dat de cryptex in het tekstbestand schijf per schijf wordt voorgesteld, terwijl dezelfde cryptex in de inleiding ring per ring werd voorgesteld.

Definieer een klasse Cryptex waarmee cryptexen kunnen voorgesteld worden. Bij het aanmaken van een object van de klasse Cryptex moet de locatie (str) van een tekstbestand met de omschrijving van een cryptex doorgegeven worden. Hierbij moet gelden dat:

Als niet aan deze voorwaarden voldaan is, dan moet een AssertionError opgeworpen worden met de boodschap ongeldige schijven.

Er is juist één combinatie waarmee een cryptex kan ontgrendeld worden. Na het aanmaken van een Cryptex object is dit standaard de combinatie die initieel voorkomt op ring 0. In plaats daarvan kan bij het aanmaken van een Cryptex object aan een optionele tweede parameter combinatie ook nog de combinatie (str) doorgegeven worden waarmee de cryptex kan ontgrendeld worden. Als de gegeven combinatie niet één van de $$m^n$$ combinaties is waarop de cryptex kan ingesteld worden, dan moet een AssertionError opgeworpen worden met de boodschap ongeldige combinatie.

Als er een Cryptex object wordt doorgegeven aan de ingebouwde functie str dan moet een stringvoorstelling (str) van de cryptex teruggegeven worden die bestaat uit $$m$$ regels. Elk van die regels beschrijft een ring van de cryptex, te beginnen bij ring 0. De karakters van elke ring worden telkens van elkaar gescheiden door één enkele spatie. Voorts moet de klasse Cryptex minstens de volgende methoden ondersteunen:

Voorbeeld

In onderstaande voorbeeldsessie gaan we ervan uit dat het tekstbestand cryptex.txt3 zich in de huidige directory bevindt.

>>> cryptex = Cryptex('cryptex.txt4')
>>> cryptex.ring(0)
'AAAAA'
>>> print(cryptex)
A A A A A
D E E C D
E I I D E
G L L E  
H N N K H
L O O L K
M P R N R
R R S R S
S T T S T
W U U T Y
>>> cryptex.ontgrendeld()
True

>>> cryptex.instellen('APPLE')
Traceback (most recent call last):
AssertionError: ongeldige combinatie

>>> cryptex.instellen('HOUSE')
>>> cryptex.ring(0)
'AAAAA'
>>> print(cryptex)
A A A A A
D E E C D
E I I D E
G L L E  
H N N K H
L O O L K
M P R N R
R R S R S
S T T S T
W U U T Y
>>> cryptex.ontgrendeld()
False

>>> cryptex.roteer({0:4})
>>> cryptex.ring(0)
'HAAAA'
>>> print(cryptex)
H A A A A
L E E C D
M I I D E
R L L E  
S N N K H
W O O L K
A P R N R
D R S R S
E T T S T
G U U T Y
>>> cryptex.ontgrendeld()
False

>>> cryptex.roteer({1:5, 3:5})
>>> cryptex.ring(0)
'HOALA'
>>> print(cryptex)
H O A L A
L P E N D
M R I R E
R T L S  
S U N T H
W A O A K
A E R C R
D I S D S
E L T E T
G N U K Y
>>> cryptex.ontgrendeld()
False

>>> cryptex.roteer({2:-1, 3:3, 4:12})
>>> cryptex.ring(0)
'HOUSE'
>>> print(cryptex)
H O U S E
L P A T  
M R E A H
R T I C K
S U L D R
W A N E S
A E O K T
D I R L Y
E L S N A
G N T R D
>>> cryptex.ontgrendeld()
True

Epiloog

In hoofdstuk 47 van Dan Brown's De Da Vinci Code vinden agente Sophie Deneuve en professor Robert Langdon een cryptex in een houten kistje.

Het was een stenen cilinder van glanzend wit marmer, met ongeveer de afmetingen van een blik tennisballen. De cilinder was echter niet een eenvoudige kolom van steen, maar leek uit vele delen te bestaan. Vijf schijven van marmer, elk ter grootte van een donut, waren op elkaar gestapeld en aan elkaar bevestigd door middel van een teer, geel koperen frame. Het geheel zag eruit als een soort kokervormige caleidoscoop met meerdere draaischijven. Aan beide uiteinden van de cilinder zat een afsluiter, ook van marmer, zodat het onmogelijk was erin te kijken. Omdat hij vloeistof had horen klotsen, nam Langdon aan dat de cilinder hol was.

Lees meer …5