Het vier-vierkantencijfer is een versleutelingsmethode die werd uitgevonden door de bekende Franse cryptograaf Félix Marie Delastelle1 (1840–1902). Deze codeertechniek maakt gebruik van vier $$5 \times 5$$ roosters. Elk van deze roosters bevat alle letters van het alfabet juist één keer, behalve de letter J. Bij het coderen en decoderen van berichten wordt de letter J immers altijd gelijkgesteld aan de letter I. De roosters linksboven en rechtsonder zijn de zogenaamde plaintext squares en bevatten van links naar rechts en van boven naar onder de letters in alfabetische volgorde. De roosters rechtsboven en linksonder zijn de zogenaamde ciphertext squares en bevatten een permutatie van de letters van het alfabet.

Een ciphertext square wordt opgebouwd door eerst de posities van het rooster van links naar rechts, en van boven naar onder in te vullen met de letters van een sleutelwoord. Hierbij worden dubbele letters slechts één keer ingevuld. Daarna worden de overige posities van het rooster ingevuld met de resterende letters van het alfabet (de letters die nog niet in het rooster voorkwamen). Zowel bij het invullen van de letters van het sleutelwoord, als bij het invullen van de letters van het alfabet wordt de letter J gelijkgesteld aan de letter I. Het vier-vierkantencijfer maakt gebruik van twee sleutelwoorden, die respectievelijk gebruikt worden voor het opbouwen van de roosters rechtsboven en linksonder.

Hieronder tonen we bijvoorbeeld de roosters die gebruikt worden bij het vier-vierkantencijfer met de sleutelwoorden VOORBEELD en SLEUTELWOORD. Om de visuele voorstelling nog duidelijker te maken, hebben we de plaintext squares in kleine letters gezet, en de ciphertext squares in hoofdletters.

a b c d e     V O R B E
f g h i k     L D A C F
l m n o p     G H I K M
q r s t u     N P Q S T
v w x y z     U W X Y Z

S L E U T     a b c d e
W O R D A     f g h i k
B C F G H     l m n o p
I K M N P     q r s t u
Q V X Y Z     v w x y z

Om een gegeven bericht te coderen, worden de volgende stappen uitgevoerd:

  1. Deel het bericht op in bigrammen (groepen van twee letters). Karakters in het bericht die geen letter zijn (leestekens, spaties, …) worden hierbij genegeerd. Indien het gegeven bericht uit een oneven aantal letters bestaat, dan wordt achteraan het bericht een extra letter Q toegevoegd. Op die manier wordt de tekst HELLO WORLD! als volgt opgedeeld in bigrammen:

    HE LL OW OR LD
  2. Zoek de eerste letter van het oorspronkelijke bigram in het rooster linksboven.

    a b c d e     V O R B E
    f g h i k     L D A C F
    l m n o p     G H I K M
    q r s t u     N P Q S T
    v w x y z     U W X Y Z
    
    S L E U T     a b c d e
    W O R D A     f g h i k
    B C F G H     l m n o p
    I K M N P     q r s t u
    Q V X Y Z     v w x y z
  3. Zoek de tweede letter van het oorspronkelijke bigram in het rooster rechtsonder.

    a b c d e     V O R B E
    f g h i k     L D A C F
    l m n o p     G H I K M
    q r s t u     N P Q S T
    v w x y z     U W X Y Z
    
    S L E U T     a b c d e
    W O R D A     f g h i k
    B C F G H     l m n o p
    I K M N P     q r s t u
    Q V X Y Z     v w x y z
  4. De eerste letter van het gecodeerde bigram staat op dezelfde rij als de eerste letter van het oorspronkelijke bigram en op dezelfde kolom als de tweede letter van het oorspronkelijke bigram.

    a b c d e     V O R B E
    f g h i k     L D A C F
    l m n o p     G H I K M
    q r s t u     N P Q S T
    v w x y z     U W X Y Z
    
    S L E U T     a b c d e
    W O R D A     f g h i k
    B C F G H     l m n o p
    I K M N P     q r s t u
    Q V X Y Z     v w x y z
  5. De tweede letter van het gecodeerde bigram staat op dezelfde rij als de tweede letter van het oorspronkelijke bigram en op dezelfde kolom als de eerste letter van het oorspronkelijke bigram.

    a b c d e     V O R B E
    f g h i k     L D A C F
    l m n o p     G H I K M
    q r s t u     N P Q S T
    v w x y z     U W X Y Z
    
    S L E U T     a b c d e
    W O R D A     f g h i k
    B C F G H     l m n o p
    I K M N P     q r s t u
    Q V X Y Z     v w x y z

Op basis van het vier-vierkantencijfer dat we hierboven als voorbeeld gebruikt hebben, kunnen we het bericht "Help me Obi-Wan Kenobi" dus als volgt coderen:

he lp me ob iw an ke no bi
FE MB ML HU DY RB FT KF BO

We geven hieronder nogmaals de vier roosters die gebruikt worden bij het coderen, waarbij we de letters weggewerkt hebben die niet gebruikt worden bij het omzetten van het oorspronkelijke bigram he naar het gecodeerde bigram FE.

- - - - -     - - - - -
- - h - -     - - - - F
- - - - -     - - - - -
- - - - -     - - - - -
- - - - -     - - - - -

- - E - -     - - - - e
- - - - -     - - - - -
- - - - -     - - - - -
- - - - -     - - - - -
- - - - -     - - - - -

Hierdoor is het onmiddellijk duidelijk dat het coderen van een bigram neerkomt op het opzoeken van de twee andere hoekpunten van de rechthoek die bepaald wordt door de twee letters in de plaintext squares. Het gecodeerde bigram wordt dan eenvoudigweg gevormd door de letters op de twee andere hoekpunten die in de ciphertext squares liggen, waarbij de letter in het rooster rechtsboven eerst komt.

Om een gecodeerd bericht te ontcijferen moeten we enkel het proces omkeren. De letters van een gecodeerd bigram moeten opgezocht worden in de roosters rechtsboven (eerste letter) en linksonder (tweede letter). Daarna kunnen de twee andere hoekpunten van de rechthoek bepaald worden. Op deze hoekpunten worden de letters van het oorspronkelijke bigram gevonden, waarbij de eerste letter terug te vinden is in het rooster linksboven.

Opgave

Definieer een klasse Vierkant waarmee de $$5 \times 5$$ roosters kunnen voorgesteld worden die gebruikt worden bij het vier-vierkantencijfer. De rijen van het rooster worden van boven naar onder geïndexeerd vanaf nul, en de kolommen worden van links naar rechts geïndexeerd vanaf nul. De klasse Vierkant moet minstens de volgende methoden ondersteunen:

Gebruik de klasse Vierkant om een klasse VierVierkant te definiëren waarmee teksten kunnen gecodeerd en gedecodeerd worden volgens het vier-vierkantencijfer met twee gegeven sleutelwoorden. Bij het coderen en decoderen mag nooit onderscheid gemaakt worden tussen hoofdletters en kleine letters, en moet de letter J altijd gelijkgesteld worden aan de letter I. In gecodeerde en gedecodeerde berichten moeten alle letters uitgeschreven worden als hoofdletters, en wordt de letter I/J genoteerd als de letter I. Deze klasse moet minstens de volgende methoden ondersteunen:

Voorbeeld

>>> vierkant = Vierkant()
>>> print(vierkant)
A B C D E
F G H I K
L M N O P
Q R S T U
V W X Y Z
>>> vierkant.letter(3, 2)
'S'
>>> vierkant.letter(7, 1)
Traceback (most recent call last):
AssertionError: ongeldige positie
>>> vierkant.positie('A')
(0, 0)
>>> vierkant.positie('?')
Traceback (most recent call last):
AssertionError: ongeldige letter

>>> vierkant = Vierkant('VOORBEELD')
>>> print(vierkant)
V O R B E
L D A C F
G H I K M
N P Q S T
U W X Y Z
>>> vierkant.letter(3, 2)
'Q'
>>> vierkant.positie('A')
(1, 2)

>>> vierkant = Vierkant('sleutelwoord')
>>> print(vierkant)
S L E U T
W O R D A
B C F G H
I K M N P
Q V X Y Z
>>> vierkant.letter(3, 2)
'M'
>>> vierkant.positie('a')
(1, 4)

>>> codec = VierVierkant('VOORBEELD', 'sleutelwoord')
>>> codec.codeer('Help me Obi-Wan Kenobi!')
'FEMBMLHUDYRBFTKFBO'
>>> codec.decodeer('FEMBMLHUDYRBFTKFBO')
'HELPMEOBIWANKENOBI'