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

ciphertext

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)

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)circular key (rainbow encryption)circular key (rainbow encryption)

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)

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.txt with the string representation of the initial state of the sample key. The example also use our sample plaintext and ciphertext.

>>> key = Rainbow('key.txt')
>>> 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.txt')
>>> 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.txt')
>>> 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)sample key (state after 1 character)sample key (state after 2 characters)sample key (state after 3 characters)

Epilogue

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

flaming rainbow

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