Blinkenlights is a neologism from hacker culture, originally referring to the diagnostic lights on the front panels of old mainframe computers from the 1960s and 1970s. According to the Jargon File1, the term dates back to the 1950s and was seen worldwide in the 1960s. More recently, the term has been applied to status lights on modern network hardware (modems, network hubs, etc.). Blinkenlights disappeared from newer computers for a number of reasons, the most important being the fact that with faster CPUs, a human could no longer interpret what was going on in the computer on the fly. Although more sophisticated UI2 mechanisms have since been developed, blinkenlights may still be present as additional status indicators and familiar skeuomorphs3.
The term is taken from a famous (often black-letter Gothic5) mock warning sign written in a garbled form of German. Variants of the sign have been relatively common in computer rooms in English-speaking countries since the early 1960s. German hackers6, in turn, has developed their own versions of the blinkenlights poster, in broken English.
Plaintext and ciphertext are two concepts from cryptography — from Ancient Greek: κρυπτός (kryptós, "hidden, secret") and γράφειν (gráphein, "to write") —the practice and study of techniques for secure communication in the presence of adversarial behavior. Prior to the modern era, cryptography was virtually synonymous with encryption, the process of converting human-readable information (plaintext) into unintelligible nonsense text (ciphertext) that can only be read by reversing the process (decryption).
A cipher is a pair of algorithms for performing encryption and, conversely, decryption. The detailed operation of a cipher is controlled by both the algorithm and a "key": a secret string of characters (ideally short so that it is easy to remember) that is needed to decrypt the ciphertext.
We have encrypted messages using a technique where the key and the ciphertext have the same length (the same number of characters). Decryption is done by superimposing the key over the ciphertext. We'll use this key and ciphertext as an example:
key: e = 2.718281828459045235360287471352662497757247093699959574966967627724076 ciphertext: 28 ZsTpaumnrhsrkotDscf nameggi cit rhi reenfeie tüd enomntpeikadrtnenbu !g
First, we scan the key from left to right, looking for the position where the digit 0 appears for the first time. At the same position in the ciphertext, we find the first character of the plaintext: the capital D at position 18 in the example (if characters are numbered from left to right, starting with zero). Then we scan the key again from the beginning, looking for the position where the digit 1 appears for the first time. At the same position in the ciphertext we find the second character of the plaintext: the letter a at position 7 in the example. We repeat this to find where the digits 2–9 appear for the first time in the key: in the example we successively find the letter s (under the first 2 at position 4), a space (under the first 3 at position 22), the letter k (under the first 4 at position 15), the letter o (under the first 5 at position 16), the letter m (under the first 6 at position 25), the letter p (under the first 7 at position 6), the letter u (under the first 8 at position 8) and the letter t (under the first 9 at position 17).
After scanning the key for the first occurrences of the digits 0–9, we repeat the process, this time scanning for the second occurrences of the digits 0–9. The next characters of the plaintext are found at those positions in the ciphertext. We repeat this procedure to successively scan the key, looking for positions where the digits 0–9 appear for the third time, the fourth time, …. If a digit $$d$$ occurs less than $$i$$ times in the key, no new character is added to the plaintext when we scan the key for the $$i$$-th occurrence of the digit $$d$$. Decryption stops once we have added characters from the ciphertext to the plaintext for every digit in the key.
This, the plaintext is as long (contains as many characters) as the number of digits in the key. The characters in the ciphertext that do not match a digit in the key are not included in the plaintext. As a result, the plaintext can be shorter than both the ciphertext and the key. This is the plaintext we get for our example ciphertext and key:
plaintext: Das komputermaschine ist nicht für der gefingerpoken und mittengraben!
Your task:
Write a function digit_count that takes a string $$s$$ (str) and returns the number of digits (int) in the string $$s$$.
Write a function digit_position that takes three arguments: i) a digit $$d$$ (int; $$0 \leq d \leq 9$$), ii) an integer $$i$$ (int; $$i \in \mathbb{N}_0$$) and iii) a string $$s$$ (str). The function must return the value -1 (int) if the digit $$d$$ occurs less than $$i$$ times in the string $$s$$. Otherwise, the function must return the position (int) in the string $$s$$ where the digit $$d$$ occurs for the $$i$$-the time. Character positions in string $$s$$ are numbered from left to right, starting with zero. Occurrences are also counted from left to right.
Write a function decrypt that takes two arguments: i) a ciphertext $$c$$ (str) and ii) the decryption key $$k$$ (str). The function must return the plaintext (str) obtained when applying the above decryption algorithm to the ciphertext $$c$$ with the key $$k$$.
>>> ciphertext = '28 ZsTpaumnrhsrkotDscf nameggi cit rhi reenfeie tüd enomntpeikadrtnenbu !g'
>>> key = 'e = 2.718281828459045235360287471352662497757247093699959574966967627724076'
>>> digit_count(key)
70
>>> digit_position(3, 2, key)
24
>>> digit_position(6, 3, key)
37
>>> digit_position(9, 42, key)
-1
>>> decrypt(ciphertext, key)
'Das komputermaschine ist nicht für der gefingerpoken und mittengraben!'
>>> ciphertext = ' ftLsrnUisyTelvWya les Kahen Eu9ocr RRll 5ochyV.!s ynle5ITiRta'
>>> key = '6630295(160n897o0338533q1=884868J7Z624$fJ035W3375E13016898B4X9.74'
>>> decrypt(ciphertext, key)
'Listen very carefully. I shall say this only once!'
As suggested by the "Listen very carefully. I shall say this only once!" quote used in the example, we took inspiration from the British comedy series 'Allo 'Allo!7 to test the solutions submitted. Originally broadcast on the BBC between 1982 and 1992 (85 episodes), the series focuses on the life of a French café owner in the town of Nouvion, during the German occupation of France in World War II, as he deals with the problems of a dishonest German officer, the local French Resistance, the handling of a stolen painting and a pair of trapped British airmen, all while concealing from his wife the affairs he is having with his waitresses. The series was devised and created in part as a parody of wartime drama Secret Army8 by Jeremy Lloyd9 and David Croft10, who also wrote most of the episodes. The series starred Gorden Kaye11, Carmen Silvera12, Vicki Michelle13 and Sue Hodge14.
The main characters of the series were of four different nationalities
— French, German, English and Italian. Lloyd and Croft portrayed
this by having the non-English characters speak English with the accent
of the foreign language, while the English characters spoke with an
upper-class English accent. The French, German and Italian characters
could understand each other when speaking, but the English characters
could not understand the others without someone "translating" for them
and vice versa.
The police officer Crabtree was introduced in the second series. Because
the character was an undercover Englishman with a poor grasp of French,
the actor, Arthur Bostrom, spoke perfectly when the character spoke in
English, but extensively deployed malapropisms to represent when the
character was speaking in French. Bostrom would changes certain words in
his lines, substituting different vowels or consonants, turning them
into different or nonsensical words, usually loaded with innuendo. An
example is the line "I was passing by the door, and I thought I would
drop in", which Bostrom pronounced "I was pissing by the door,
and I thought I would drip in". Another example is Crabtree's
greeting of "good morning", pronounced "good moaning15".