Plugboard.py
This class represents the plugboard of the Enigma machine, which allows for the swapping of letter pairs before and after the main rotor encryption process.
class Plugboard:
def __init__(self, pairs):
self.left = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
self.right = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
for pair in pairs:
A = pair[0]
B = pair[1]
pos_a = self.left.find(A)
pos_b = self.left.find(B)
self.left = self.left[:pos_a] + B + self.left[pos_a+1:]
self.left = self.left[:pos_b] + A + self.left[pos_b+1:]
def forward(self, signal):
letter = self.right[signal]
signal = self.left.find(letter)
return signal
def backward(self, signal):
letter = self.left[signal]
signal = self.right.find(letter)
return signal
Rotar.py
This class represents a single rotor in the Enigma machine. Rotors advance with each keypress and scramble the signal in a unique way based on their wiring.
class Rotor:
def __init__(self, wiring, notch):
self.left = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
self.right = wiring
self.notch = notch
def forward(self, signal):
letter = self.right[signal]
signal = self.left.find(letter)
return signal
def backward(self, signal):
letter = self.left[signal]
signal = self.right.find(letter)
return signal
def show(self):
print(self.left)
print(self.right)
print()
def rotate(self, n=1):
for _ in range(n):
self.left = self.left[1:] + self.left[0]
self.right = self.right[1:] + self.right[0]
def rotate_to_letter(self, letter):
n = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".find(letter)
self.rotate(n)
Enigma.py
This class represents the Enigma machine, which combines the keyboard, plugboard, rotors, and reflector. The set_key
method sets the initial rotor positions, and the encrypt
method handles the encryption process for a single letter.
class Enigma:
def __init__(self, kb, pb, r1, r2, r3, re):
self.kb = kb
self.pb = pb
self.r1 = r1
self.r2 = r2
self.r3 = r3
self.re = re
def set_key(self, key):
self.r1.rotate_to_letter(key[0])
self.r2.rotate_to_letter(key[1])
self.r3.rotate_to_letter(key[2])
def encrypt(self, letter):
if self.r2.left[0] == self.r2.notch and self.r3.left[0] == self.r3.notch:
self.r1.rotate()
self.r2.rotate()
self.r3.rotate()
elif self.r3.left[0] == self.r3.notch:
self.r2.rotate()
self.r3.rotate()
else:
self.r3.rotate()
signal = self.kb.forward(letter)
signal = self.pb.forward(signal)
signal = self.r3.forward(signal)
signal = self.r2.forward(signal)
signal = self.r1.forward(signal)
signal = self.re.reflector(signal)
signal = self.r1.backward(signal)
signal = self.r2.backward(signal)
signal = self.r3.backward(signal)
signal = self.pb.backward(signal)
letter = self.kb.backward(signal)
return letter
Main.py
This is the main script that puts together all components of the Enigma machine and demonstrates its usage with an example encryption.
from key_board import Keyboard
from plugboard import Plugboard
from rotor import Rotor
from reflect import Reflect
from enigma import Enigma
I = Rotor("EKMFLGDQVZNTOWYHXUSPAIBRCJ", "Q")
II = Rotor("AJDKSIRUXBLHWTMCQGZNPYFVOE", "E")
III = Rotor("BDFHJLCPRTXVZNYEIWGAKMUSQO", "V")
IV = Rotor("ESOVPZJAYQUIRHXLNFTGKDCMWB", "J")
V = Rotor("VZBRGITYUPSDNHLXAWMJQOFECK", "Z")
A = Reflect("EJMZALYXVBWFCRQUONTSPIKHGD")
B = Reflect("YRUHQSLDPXNGOKMIEBFZCWVJAT")
C = Reflect("FVPJIAOYEDRZXWGCTKUQSBNMHL")
KB = Keyboard()
PB = Plugboard(["AR", "GK", "OX"])
ENIGMA = Enigma(KB, PB, I, II, III, A)
op = ""
ENIGMA.set_key("DOG")
for msg in "NGMC":
op = op + ENIGMA.encrypt(msg)
print(op)
# print(ENIGMA.encrypt("A"))