De Special Operations Executive1 — afgekort SOE — was een van de zeven geheime diensten die door de Britse regering werden opgericht tijdens de Tweede Wereldoorlog. Deze organisatie maakte gebruik van poëzie om in het geheim te communiceren met haar spionnen in vijandelijke gebieden. Daarbij spraken afzender en ontvanger op voorhand af welk gedicht ze zouden gebruiken. Door de opeenvolgende letters van het gedicht te nummeren, ontstond een eenvoudige sleutel die kon gebruikt worden om berichten te coderen en decoderen. Omdat beide partijen het gedicht van buiten konden leren, was er ook geen codeboek dat verloren kon geraken. Toch konden de nazi's de code vrij makkelijk breken, vooral als het om een bekend gedicht ging.

Toen SOE-officier Leo Marks2 dit begon door te hebben, introduceerde hij een aantal zelfgeschreven gedichten. Deze gaf hij in maart 1944 aan de Franse agente Violette Szabo3:

The life that I have is all that I have,
And the life that I have is yours.
The love that I have of the life that I have
Is yours and yours and yours.

A sleep I shall have, a rest I shall have,
Yet death will be but a pause.
For the peace of my years in the long green grass
Will be yours and yours and yours.

Marks had het drie maanden daarvoor geschreven, ter nagedachtenis aan zijn vriendin Ruth die in Canada was omgekomen bij een vliegtuigongeluk. Het gedicht werd wereldberoemd toen het werd voorgelezen in de film Carve Her Name with Pride4 uit 1958, over de exploten van Szabo in de oorlog. Helaas werd Szabo zelf gevangen genomen, gemarteld en vermoord voordat ze berichten naar elkaar konden verzenden.

Opgave

De sleutel van een SOE-code wordt bepaald aan de hand van de tekst van een gedicht, door daarin alle opeenvolgende letters te nummeren vanaf één. Daarbij worden karakters die geen letter zijn genegeerd. Gevraagd wordt:

Voorbeeld

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

>>> sleutel = versleutel('gedicht.txt6')
>>> sleutel['C']
{177}
>>> sleutel['A']
{10, 14, 19, 24, 28, 31, 43, 47, 66, 70, 84, 88, 98, 106, 114, 123, 127, 130, 138, 142, 150, 162, 164, 176, 185, 204, 218, 226}
>>> sleutel['R']
{55, 96, 104, 112, 131, 170, 186, 198, 203, 216, 224, 232}
>>> sleutel['K']
Traceback (most recent call last):
KeyError: 'K'

>>> reconstrueer(sleutel)
'THELIFETHATIHAVEISALLTHATIHAVEANDTHELIFETHATIHAVEISYOURSTHELOVETHATIHAVEOFTHELIFETHATIHAVEISYOURSANDYOURSANDYOURSASLEEPISHALLHAVEARESTISHALLHAVEYETDEATHWILLBEBUTAPAUSEFORTHEPEACEOFMYYEARSINTHELONGGREENGRASSWILLBEYOURSANDYOURSANDYOURS'

>>> codeer('Carve Her Name With Pride', sleutel)
[177, 176, 198, 128, 132, 9, 200, 55, 99, 47, 181, 77, 153, 26, 41, 9, 163, 232, 188, 108, 184]
>>> codeer('Carve Her Name With Pride', sleutel)
[177, 123, 112, 29, 173, 76, 16, 232, 195, 204, 181, 40, 153, 26, 11, 76, 119, 104, 120, 228, 173]
>>> codeer('The Wind That Shakes the Barley', sleutel)
[190, 42, 175, 153, 68, 227, 220, 75, 69, 19, 34, 51, 9, 164, 0, 118, 18, 41, 65, 144, 211, 130, 112, 78, 59, 93]

>>> decodeer([177, 176, 198, 128, 132, 9, 200, 55, 99, 47, 181, 77, 153, 26, 41, 9, 163, 232, 188, 108, 184], sleutel)
'CARVEHERNAMEWITHPRIDE'
>>> decodeer([177, 123, 112, 29, 173, 76, 16, 232, 195, 204, 181, 40, 153, 26, 11, 76, 119, 104, 120, 228, 173], sleutel)
'CARVEHERNAMEWITHPRIDE'
>>> decodeer([190, 42, 175, 153, 68, 227, 220, 75, 69, 19, 34, 51, 9, 164, 0, 118, 18, 41, 65, 144, 211, 130, 112, 78, 59, 93], sleutel)
'THEWINDTHATSHA?ESTHEBARLEY'