Bij de regenboogversleuteling bestaat een cijfertekst (een gecodeerd bericht) uit een reeks gekleurde karakters.

Een sleutel voor de regenboogversleuteling bestaat uit $$m$$ concentrische cirkels die elk $$n$$ karakters bevatten. Elke cirkel heeft een unieke kleur, corresponderend met de kleuren van de karakters in de cijfertekst. Geen enkel karakter komt meer dan één keer in de sleutel voor. De sleutel bevat dus $$m \times n$$ verschillende karakters. Dit zijn minstens alle karakters die in de cijfertekst en in de klare tekst (het originele bericht) voorkomen.

De $$n$$ karakters langs elke cirkel staan op vaste posities rond de concentrische cirkels. Het feit dat daardoor op dezelfde positie langs de cirkels telkens $$m$$ karakters staan (één op elke cirkel), speelt een belangrijke rol bij de regenboogversleuteling.
De gekleurde karakters van een cijfertekst worden van links naar rechts gedecodeerd. Het eerste karakter van de voorbeeld cijfertekst is bijvoorbeeld een rode J. Dat betekent dat we voor het decoderen moeten kijken naar het karakter langs de rode cirkel dat op dezelfde positie staat als het karakter J. Het karakter J staat zelf langs de blauwe cirkel. Langs de rode cirkel staat op diezelfde positie het karakter S. Dat is het eerste karakter van de klare tekst.
Na het decoderen van een gekleurd karakter uit de cijfertekst, roteert de cirkel met de kleur van dat karakter over één karakterpositie. Sommige cirkels in de sleutel roteren in wijzerzin en andere in tegenwijzerin. Zoals aangegeven door de pijlen, roteren in de voorbeeldsleutel de groene, gele en roze cirkels in wijzerin, en de rode en blauwe cirkels in tegenwijzerzin. Na het decoderen van de rode J roteert de rode cirkel dus één karakterpositie in tegenwijzerzin.



Het tweede karakter van de cijfertekst is een roze C. Het karakter C staat zelf langs de groene cirkel. Op dezelfde positie staat langs de roze cirkel het karakter o. Dat is dus het tweede karakter van de klare tekst. Daarna roteren we de roze cirkel één karakterpositie in wijzerzin.
Het derde karakter van de cijfertekst is een gele b. Het karakter b staat zelf langs de groene cirkel. Op dezelfde positie staat langs de gele cirkel het karakter m. Dat is dus het derde karakter van de klare tekst. Daarna roteren we de gele cirkel één karakterpositie in wijzerzin.
Als we op die manier de voorbeeld cijfertekst volledig decoderen, dan krijgen we als klare tekst
Somewhere over the Rainbow.
De kleur van een karakter in een cijfertekst en van een cirkel in een sleutel voor de regenboogversleuteling stellen we voor door een unieke hoofdletter (str). Voor onze voorbeeld cijfertekst en sleutel gebruiken we bijvoorbeeld R voor rood (red), G voor groen (green), Y voor geel (yellow), B voor blauw (blue) en P voor roze (pink).
Een gekleurd karakter in een cijfertekst beschrijven we dan als de hoofdletter die correspondeert met de kleur, gevolgd door het karakter zelf. Zo staat RJ voor een rode J, PC voor een roze C, en Yb voor een gele b. De stringvoorstelling van een cijfertekst krijgen we door de beschrijvingen van alle gekleurde karakters uit de cijfertekst achter elkaar te zetten. De voorbeeld cijfertekst wordt dan voorgesteld als
RJPCYbBGGSGcByR2BhYUPMRQBIRVYPYgGqBbYSYpYcBNPJGsPYG1PT
Omdat de $$n$$ karakters langs de concentrische cirkels van een sleutel tegenover elkaar staan uitgelijnd, kunnen we de posities van de karakters in wijzerzin nummeren van $$0$$ tot $$n$$ vanaf de bovenkant van de cirkels. Daardoor kunnen we de sleutel ook op een vlakke manier voorstellen. De karakters langs elke cirkel worden van links naar rechts opgelijst in volgorde van hun positie ($$0 \ldots n - 1$$) langs de cirkel, en de cirkels worden van boven naar onder opgelijst in concentrische volgorde van buiten naar binnen. De pijlen geven aan of de cirkels in wijzerzin (pijl naar rechts aan de rechterkant) of in tegenwijzerzin (pijl naar links aan de linkerkant) roteren. De begintoestand van de voorbeeldsleutel kan bijvoorbeeld vlak voorgesteld worden als

De stringvoorstelling van een sleutel volgt deze vlakke voorstelling. Elke regel van de stringvoorstelling beschrijft een concentrische cirkel (van buiten naar binnen). Het eerste karakter is een hoofdletter die de kleur van de cirkel voorstelt. Het tweede karakter geeft de rotatierichting van de cirkel aan: > voor wijzerzin en < voor tegenwijzerzin. Daarna volgen de karakters langs de cirkel in volgorde van hun positie ($$0 \ldots n - 1$$). Dit is dan de stringvoorstelling van de begintoestand van de voorbeeldsleutel:
R<kTSLrWvgpKF, G>ywQYCOXdbxDh Y>tuaMsl Zmq-R B<PcJeH2f0iBU1 P<zNGEo.n3AjIV
Definieer een klasse Regenboog waarmee sleutels van de regenboogversleuteling kunnen voorgesteld worden, die we kunnen gebruiken om berichten te coderen en te decoderen. Bij het aanmaken van een nieuwe sleutel (Regenboog) moet de locatie (str) doorgegeven worden van een tekstbestand met de stringvoorstelling van de begintoestand van de sleutel.
Als er een sleutel $$\mathcal{R}$$ (Regenboog) wordt doorgegeven aan de ingebouwde functie str, dan moet die de stringvoorstelling (str) van sleutel $$\mathcal{R}$$ teruggeven. Die stringvoorstelling moet de huidige positie van de karakters langs de concentrische cirkels weergeven, ook na het roteren van de cirkels.
Op een sleutel $$\mathcal{R}$$ (Regenboog) met $$m$$ cirkels en $$n$$ karakters langs elke cirkel moet je minstens de volgende methoden kunnen aanroepen:
Een methode karakter waaraan twee argumenten moeten doorgegeven worden: i) de kleur $$K$$ (str) van een cirkel in sleutel $$\mathcal{R}$$ en ii) een positie $$i$$ (int; $$0 \leq i < n$$) langs de cirkels in sleutel $$\mathcal{R}$$. De methode moet het karakter (str) teruggeven dat voorkomt op positie $$i$$ langs de cirkel met kleur $$K$$ in sleutel $$\mathcal{R}$$.
Een methode positie waaraan een karakter $$\alpha$$ (str) uit sleutel $$\mathcal{R}$$ moet doorgegeven worden. De methode moet een tuple teruggeven met twee elementen: i) de kleur (str) van de cirkel waarlangs karakter $$\alpha$$ voorkomt in sleutel $$\mathcal{R}$$, en ii) de positie (int) van karakter $$\alpha$$ in sleutel $$\mathcal{R}$$.
Een methode roteer waaraan de kleur $$K$$ (str) van een cirkel in sleutel $$\mathcal{R}$$ moet doorgegeven worden. De methode moet in sleutel $$\mathcal{R}$$ de cirkel met kleur $$K$$ over één karakterpositie roteren in zijn rotatierichting (wijzerzin of tegenwijzerzin) en een referentie naar sleutel $$\mathcal{R}$$ teruggeven.
Een methode decodeer_karakter waaraan de kleur (str) en het karakter (str) moet doorgegeven worden van een gekleurd karakter dat gecodeerd werd volgens de regenboogversleuteling met sleutel $$\mathcal{R}$$. De methode moet het gekleurde karakter decoderen. Daarbij moet een cirkel van sleutel $$\mathcal{R}$$ geroteerd worden, en moet het gedecodeerde karakter (str) teruggeven worden.
Een methode decodeer waaraan een cijfertekst (str) moet doorgegeven worden die gecodeerd werd volgens de regenboogversleuteling met sleutel $$\mathcal{R}$$. De methode moet de corresponderende klare tekst (str) teruggeven. Bij het decoderen moet telkens een cirkel van sleutel $$\mathcal{R}$$ geroteerd worden bij het decoderen van het volgende gekleurde karakter uit de cijfertekst.
In deze interactieve sessie gebruiken we de sleutel voor de regenboogversleuteling die we in deze opgave als voorbeeld gebruikt hebben. Daarbij gaan we ervan uit dat er in de huidige directory een tekstbestand sleutel.txt1 voorkomt dat de stringvoorstelling van de begintoestand van die sleutel bevat. We gebruiken ook de klare tekst en de cijfertekst uit de opgave als voorbeeld.
>>> sleutel = Regenboog('sleutel.txt2')
>>> print(sleutel)
R<kTSLrWvgpKF,
G>ywQYCOXdbxDh
Y>tuaMsl Zmq-R
B<PcJeH2f0iBU1
P>zNGEo.n3AjIV
>>> sleutel.karakter('R', 2)
'S'
>>> sleutel.karakter('P', 4)
'o'
>>> sleutel.karakter('Y', 8)
'm'
>>> sleutel.positie('S')
('R', 2)
>>> sleutel.positie('o')
('P', 4)
>>> sleutel.positie('m')
('Y', 8)
>>> print(sleutel.roteer('R'))
R<TSLrWvgpKF,k
G>ywQYCOXdbxDh
Y>tuaMsl Zmq-R
B<PcJeH2f0iBU1
P>zNGEo.n3AjIV
>>> sleutel.positie('S')
('R', 1)
>>> sleutel.karakter('R', 1)
'S'
>>> print(sleutel.roteer('P'))
R<TSLrWvgpKF,k
G>ywQYCOXdbxDh
Y>tuaMsl Zmq-R
B<PcJeH2f0iBU1
P>VzNGEo.n3AjI
>>> sleutel.positie('o')
('P', 5)
>>> sleutel.karakter('P', 5)
'o'
>>> sleutel = Regenboog('sleutel.txt3')
>>> sleutel.decodeer_karakter('R', 'J')
'S'
>>> print(sleutel)
R<TSLrWvgpKF,k
G>ywQYCOXdbxDh
Y>tuaMsl Zmq-R
B<PcJeH2f0iBU1
P>zNGEo.n3AjIV
>>> sleutel.decodeer_karakter('P', 'C')
'o'
>>> print(sleutel)
R<TSLrWvgpKF,k
G>ywQYCOXdbxDh
Y>tuaMsl Zmq-R
B<PcJeH2f0iBU1
P>VzNGEo.n3AjI
>>> sleutel.decodeer_karakter('Y', 'b')
'm'
>>> print(sleutel)
R<TSLrWvgpKF,k
G>ywQYCOXdbxDh
Y>RtuaMsl Zmq-
B<PcJeH2f0iBU1
P>VzNGEo.n3AjI
>>> sleutel = Regenboog('sleutel.txt4')
>>> sleutel.decodeer('RJPCYbBGGSGcByR2BhYUPMRQBIRVYPYgGqBbYSYpYcBNPJGsPYG1PT')
'Somewhere over the Rainbow.'
Dit zijn de vlakke voorstellingen van de sleutel bij het begin en na het decoderen van de eerste drie gekleurde karakters van de cijfertekst.




Wanneer zonlicht wordt gebroken door ijskristallen in cirruswolken, levert dit soms dit zeldzame verschijnsel op, dat bekend staat als een circumhorizontale boog5.

Dit gebeurt alleen maar als de zon hoog aan de hemel staat, dus er is geen pot met goud.