-
Notifications
You must be signed in to change notification settings - Fork 17
/
Copy pathexample.py
156 lines (128 loc) · 5.81 KB
/
example.py
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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
########################################################################
# COMPONENT:
# EXAMPLE
# Author:
# Br. Helfrich, Kyle Mueller
# Summary:
# A simple Caesar Cipher to show what your cipher file should contain
########################################################################
##################################################
# EXAMPLE CIPHER
##################################################
class Example:
def __init__(self):
# minimum "printable" character
self._value_minimum = ' '
# maximum "printable" character
self._value_maximum = '~'
# size of alphabet used
self._size_alphabet = ord(self._value_maximum) \
- ord(self._value_minimum) + 1
def get_author(self):
return "Brother Helfrich, adapted to Python by Kyle Mueller"
def get_cipher_name(self):
return "Caesar Cipher"
############################################################
# GET CIPHER CITATION
# Returns the citation from which we learned about the cipher
############################################################
def get_cipher_citation(self):
s = "LearnCryptography.com (2016), " \
"\"Learn Cryptography - Caesar Cipher\', \n retrieved: " \
"https://learncryptography.com/classical-encryption/caesar-cipher"
return s
############################################################
# GET PSEUDOCODE
# Returns the pseudocode as a string to be used by the caller
############################################################
def get_pseudocode(self):
# The encrypt pseudocode
pc = "encrypt(plainText, password)\n" \
" offset <- offsetFromPassword(password)\n" \
" FOR p is all values of plainText\n" \
" index <- (indexFromCharacter(*p) + offset) % size\n" \
" cipherText += characterFromIndex(index)\n" \
" RETURN cipherText\n\n"
# The decrypt pseudocode
pc += "decrypt(cipherText, password)\n" \
" offset <- size - offsetFromPassword(password)\n" \
" FOR p is all values of cipherText\n" \
" index <- (indexFromCharacter(*p) + offset) % size\n" \
" plainText += characterFromIndex(index)\n" \
" RETURN plainText\n\n"
# helper routine
pc += "offsetFromPassword(password)\n" \
" FOR p is all values of password\n" \
" offset <- indexFromCharacter(p)\n" \
" RETURN offset % size\n"
return pc
############################################################
# ENCRYPT
# Shift every value in the plaintext by a fixed amount
############################################################
def encrypt(self, plaintext, password):
ciphertext = ""
# find a Caesar password from a textual password
offset = self._offset_from_password(password)
assert offset >= 0 and offset < self._size_alphabet
# convert the plaintext one character at a time
for p in plaintext:
# convert the character into an index we can work with
index = self._index_from_character(p)
# perform the shift
index += offset
# make sure it is within range
index %= self._size_alphabet
assert index >= 0 and index < self._size_alphabet
# send the index into the ciphertext
ciphertext += self._character_from_index(index)
return ciphertext
############################################################
# DECRYPT
# Shift every value in ciphertext by a fixed amount
############################################################
def decrypt(self, ciphertext, password):
plaintext = ""
# find a Caesar password from a textual password
offset = self._offset_from_password(password)
assert offset >= 0 and offset < self._size_alphabet
# make the offset backwards
offset = self._size_alphabet - offset
assert offset >= 0 and offset < self._size_alphabet
# convert the ciphertext one character at a time
for p in ciphertext:
# convert the character into an index we can work with
index = self._index_from_character(p)
# perform the shift
index += offset
# make sure it is within range
index %= self._size_alphabet
assert index >= 0 and index < self._size_alphabet
# send the index into the ciphertext
plaintext += self._character_from_index(index)
return plaintext
###################################################
# INDEX FROM CHARACTER
# Get an index value from a given letter
###################################################
def _index_from_character(self, letter):
if letter > self._value_maximum or letter < self._value_minimum:
return 0
return ord(letter) - ord(self._value_minimum)
###################################################
# CHARACTER FROM INDEX
# Get the characer value from a given index
###################################################
def _character_from_index(self, index):
if index >= 0 and index < self._size_alphabet:
return chr(index + ord(self._value_minimum))
return ' '
###################################################
# OFFSET FROM PASSWORD
# Get the Caesar offset corresponding to a given password
###################################################
def _offset_from_password(self, password):
offset = 0
for c in password:
offset += self._index_from_character(c)
return offset % self._size_alphabet