-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathenigma.py
More file actions
104 lines (84 loc) · 2.83 KB
/
enigma.py
File metadata and controls
104 lines (84 loc) · 2.83 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
pyEnigma, a Python Enigma cypher machine simulator.
Copyright Christophe Goessen (initial author) and Cédric Bonhomme
GPLv3 license
"""
from rotor import *
class Enigma(object):
"""Represents an Enigma machine.
Initializes an Enigma machine with these arguments:
- ref: reflector;
- r1, r2, r3: rotors;
- key: initial state of rotors;
- plus: plugboard settings.
"""
def __init__(self, ref, r1, r2, r3, key="AAA", plugs="", ringset=1):
"""Initialization of the Enigma machine."""
self.reflector = ref
self.rotor1 = r1
self.rotor2 = r2
self.rotor3 = r3
self.rotor1.state = key[0]
self.rotor2.state = key[1]
self.rotor3.state = key[2]
self.reflector.state = "A"
self.ringset = ringset
plugboard_settings = [(elem[0], elem[1]) for elem in plugs.split(" ")]
alpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
alpha_out = [" "] * 26
for i in range(len(alpha)):
alpha_out[i] = alpha[i]
for k, v in plugboard_settings:
alpha_out[ord(k) - ord("A")] = v
alpha_out[ord(v) - ord("A")] = k
try:
self.transtab = str.maketrans(alpha, "".join(alpha_out))
except:
# Python 2
from string import maketrans
self.transtab = maketrans(alpha, "".join(alpha_out))
def encipher(self, plaintext_in):
"""Encrypt 'plaintext_in'."""
ciphertext = ""
plaintext_in_upper = plaintext_in.upper()
plaintext = plaintext_in_upper.translate(self.transtab)
for c in plaintext:
if self.rotor2.is_in_turnover_pos():
self.rotor2.notch()
self.rotor3.notch()
if self.rotor1.is_in_turnover_pos():
self.rotor2.notch()
self.rotor1.notch()
if not c.isalpha():
ciphertext += c
continue
t = self.rotor1.encipher_right(c)
t = self.rotor2.encipher_right(t)
t = self.rotor3.encipher_right(t)
t = self.reflector.encipher(t)
t = self.rotor3.encipher_left(t)
t = self.rotor2.encipher_left(t)
t = self.rotor1.encipher_left(t)
ciphertext += t
res = ciphertext.translate(self.transtab)
fres = ""
for idx, char in enumerate(res):
if plaintext_in[idx].islower():
fres += char.lower()
else:
fres += char
return fres
def __str__(self):
"""Pretty display."""
return """
Reflector: %s
Rotor 1: %s
Rotor 2: %s
Rotor 3: %s""" % (
self.reflector,
self.rotor1,
self.rotor2,
self.rotor3,
)