In rainbow encryption, a ciphertext (an encrypted message) is a sequence of colored characters.

ciphertext
Sample ciphertext encoded according to the rainbow encryption. The ciphertext is a sequence of colored characters, with the color of the characters being used as the background color.

A key for rainbow encryption consists of $$m$$ concentric circles, each containing $$n$$ characters. Each circle has a unique color, corresponding to the colors of the characters in the ciphertext. No character appears more than once in the key. The key therefore contains $$m \times n$$ different characters. These are at least all characters that appear in the ciphertext and in the plaintext (the original message).

circular key (rainbow encryption)
Sample key for rainbow encryption with $$m=5$$ concentric circles, each containing $$n=12$$ characters. The positions of the characters are numbered clockwise from $$0$$ to $$n=12$$ startng from the top of the circles (gray numbers on the inside and outside of the circles).

The $$n$$ characters along each circle are located at fixed positions around the concentric circles. The fact that there are $$m$$ characters at the same position along the circles (one on each circle) plays an important role in rainbow encryption.

The colored characters of a ciphertext are decoded from left to right. For example, the first character of the sample ciphertext is a red J. To decode this character, we must find the character along the red circle that is at the same position as character J. We find character J along the blue circle. At the same position along the red circle is character S. That's the first character of the plaintext.

After decoding a colored character from the ciphertext, the circle of that color rotates one character position. Some circles in the key rotate clockwise and others counterclockwise. As indicated by the arrows, in the sample key, the green, pink and yellow circles rotate clockwise, and the red and blue circles rotate counterclockwise. After decoding the red J, the red circle rotates one character position counterclockwise.

circular key (rainbow encryption)
Alignment of the characters in the sample key after decoding the red J, where the red circle was rotated one character position counterclockwise.
circular key (rainbow encryption)
Alignment of the characters in the sample key after decoding the pink C, where the pink circle was rotated one character position clockwise.
circular key (rainbow encryption)
Alignment of the characters in the sample key after decoding the yellow b, where the yellow circle was rotated one character position clockwise.

The second character of the ciphertext is a pink C. Character C is itself located along the green circle. At the same position along the pink circle is character o. That's the second character of the plaintext. We then rotate the pink circle one character position clockwise.

The third character of the ciphertext is a yellow b. Character b is itself located along the green circle. At the same position along the yellow circle is character m. That's the third character of the plaintext. We then rotate the yellow circle one character position clockwise.

If we continue decoding the sample ciphertext in this way, we obtain the plaintext

Somewhere over the Rainbow.

Assignment

We represent the color of a character in a ciphertext and of a circle in the key for rainbow encryption as a unique uppercase letter (str). For our sample ciphertext and key we use R for red, G for green, Y for yellow, B for blue, and P for pink.

A colored character in a ciphertext is described as the uppercase letter representing the color, followed by the character itself. For example, RJ stands for a red J, PC for a pink C, and Yb for a yellow b. The string representation of a ciphertext is obtained by concatenating the descriptions of all colored characters from the ciphertext. As such, the sample ciphertext is represented as

RJPCYbBGGSGcByR2BhYUPMRQBIRVYPYgGqBbYSYpYcBNPJGsPYG1PT

Because the $$n$$ characters along the concentric circles of a key are aligned against each other, we can number the positions of the characters clockwise from $$0$$ to $$n$$ starting from the top of the circles. This allows us to represent the key in a linear way. The characters along each circle are listed from left to right in order of their position ($$0 \ldots n - 1$$) along the circle, and the circles are listed from top to bottom in concentric order from outside to inside. The arrows indicate whether the circles rotate clockwise (rightward arrow on the right side) or counterclockwise (leftward arrow on the left side). For example, the initial state of the sample key can be represented in a linear way as

linear key (rainbow encryption)
Linear representation of the initial state of the sample key.

The string representation of a key follows this linear representation. Each line of the string representation describes a concentric circle (from outside to inside). The first character is an uppercase letter representing the color of the circle. The second character indicates the direction of rotation of the circle: > for clockwise and < for counterclockwise. This is followed by the characters along the circle in order of their position ($$0 \ldots n - 1$$). This is the string representation of the initial state of the sample key:

R<kTSLrWvgpKF,
G>ywQYCOXdbxDh
Y>tuaMsl Zmq-R
B<PcJeH2f0iBU1
P<zNGEo.n3AjIV

Define a class Rainbow to represent rainbow encryption keys that can be used to encode and decode messages. When creating a new key (Rainbow), the location (str) of a text file containing the string representation of the initial state of the key must be passed.

If a key $$\mathcal{R}$$ (Rainbow) is passed to the built-in function str, the string representation (str) of key $$\mathcal{R}$$ must be returned. That string representation must reflect the current positions of the characters along the concentric circles, also after rotating the circles.

A key $$\mathcal{R}$$ (Rainbow) with $$m$$ circles and $$n$$ characters along each circle must support at least the following methods:

Example

In this interactive session we use our sample key for rainbow encryption. We assume the current directory contains the text file key.txt1 with the string representation of the initial state of the sample key. The example also use our sample plaintext and ciphertext.

>>> key = Rainbow('key.txt2')
>>> print(key)
R<kTSLrWvgpKF,
G>ywQYCOXdbxDh
Y>tuaMsl Zmq-R
B<PcJeH2f0iBU1
P>zNGEo.n3AjIV
>>> key.character('R', 2)
'S'
>>> key.character('P', 4)
'o'
>>> key.character('Y', 8)
'm'
>>> key.position('S')
('R', 2)
>>> key.position('o')
('P', 4)
>>> key.position('m')
('Y', 8)
>>> print(key.rotate('R'))
R<TSLrWvgpKF,k
G>ywQYCOXdbxDh
Y>tuaMsl Zmq-R
B<PcJeH2f0iBU1
P>zNGEo.n3AjIV
>>> key.position('S')
('R', 1)
>>> key.character('R', 1)
'S'
>>> print(key.rotate('P'))
R<TSLrWvgpKF,k
G>ywQYCOXdbxDh
Y>tuaMsl Zmq-R
B<PcJeH2f0iBU1
P>VzNGEo.n3AjI
>>> key.position('o')
('P', 5)
>>> key.character('P', 5)
'o'

>>> key = Rainbow('key.txt3')
>>> key.decode_character('R', 'J')
'S'
>>> print(key)
R<TSLrWvgpKF,k
G>ywQYCOXdbxDh
Y>tuaMsl Zmq-R
B<PcJeH2f0iBU1
P>zNGEo.n3AjIV
>>> key.decode_character('P', 'C')
'o'
>>> print(key)
R<TSLrWvgpKF,k
G>ywQYCOXdbxDh
Y>tuaMsl Zmq-R
B<PcJeH2f0iBU1
P>VzNGEo.n3AjI
>>> key.decode_character('Y', 'b')
'm'
>>> print(key)
R<TSLrWvgpKF,k
G>ywQYCOXdbxDh
Y>RtuaMsl Zmq-
B<PcJeH2f0iBU1
P>VzNGEo.n3AjI

>>> key = Rainbow('key.txt4')
>>> key.decode('RJPCYbBGGSGcByR2BhYUPMRQBIRVYPYgGqBbYSYpYcBNPJGsPYG1PT')
'Somewhere over the Rainbow.'

These are the linear representations of the key in its initial state and after decoding the first three characters of the ciphertext.

sample key (initial state)
Initial state of the sample key.
sample key (state after 1 character)
State of the sample key after decoding the first character of the ciphertext. The red circle was rotated one character position counterclockwise.
sample key (state after 2 characters)
State of the sample key after decoding the second character of the ciphertext. The pink circle was rotated one character position clockwise.
sample key (state after 3 characters)
State of the sample key after decoding the third character of the ciphertext. The yellow circle was rotated one character position clockwise.

Epilogue

When sunlight is refracted through ice crystals in cirrus clouds, it sometimes produces this rare phenomenon, known as a circumhorizontal arc5.

flaming rainbow
A "flaming rainbow".

It happens only when the sun is high in the sky, so there's no pot of gold.