-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtest2.py
More file actions
151 lines (125 loc) · 6.04 KB
/
test2.py
File metadata and controls
151 lines (125 loc) · 6.04 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
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
# K-Rail Fence Cipher Algorithm Encrypt/Decrypt (Substitution Cipher)
# Leo Martinez III
# Created Sping 2024
#-------------------------------------------------------------------------------
# Encryption
# Method for performing K-Rail Fence Encryption on given plaintext
def encryptRailFence(plaintext, key):
# Filter out spaces from the plaintext (spaces are ignored for encipherment)
plaintext = "".join(plaintext.split())
# Creation of the matrix 'rail' filled with placeholders (ph)
rail = [['ph' for i in range(len(plaintext))] # length of plaintext = number of columns
for j in range(key)] # key = number of rows
# Initialized information for sense of direction and values of row/col
direction_down = False
col = 0
row = 0
for i in range(len(plaintext)):
# Check the direction of flow (is it the first row or last row?)
if (row == 0) or (row == key - 1):
direction_down = not direction_down # Invert direction if yes
# Begin filling the cipher matrix
rail[row][col] = plaintext[i]
col += 1
# Change rows based on the flag variable 'direction_down' logic
if direction_down:
row += 1
else:
row -= 1
# After the matrix has been filled, we can now extract that information to create the ciphertext
ciphertext = []
for i in range(key): # Rows
for j in range(len(plaintext)): # Columns
if rail[i][j] != 'ph': # If the value is not a placeholder, append it to the ciphertext list
ciphertext.append(rail[i][j])
return "".join(ciphertext) # Convert the ciphertext list into a singular string
#-------------------------------------------------------------------------------
# Decryption
# Method for performing n-Rail Fence Decryption on given ciphertext
def decryptRailFence(ciphertext, key):
# Creation of the matrix 'rail' filled with placeholders (similar to encryption algorithm)
rail = [['*' for i in range(len(ciphertext))]
for j in range(key)]
## Initialized information for sense of direction and values of row/col
direction_down = None
col = 0
row = 0
# Create markers on the matrix with 'mkr'
for i in range(len(ciphertext)):
if row == 0: # Highest level row
direction_down = True
if row == key - 1: # Lowest level row
direction_down = False
# Begin filling the matrix with markers based on the key and length of text
rail[row][col] = 'mkr'
col += 1
# Change row index based on the flag variable 'direction_down' logic
if direction_down:
row += 1
else:
row -= 1
# For loop to begin filling marked spots with characters from the ciphertext
# idx = indexing for ciphertext, i = row index, j = col index
idx = 0
for i in range(key):
for j in range(len(ciphertext)):
if ((rail[i][j] == 'mkr') and
(idx < len(ciphertext))):
rail[i][j] = ciphertext[idx]
idx += 1
# Begin reading the filled rail matrix in a zigzag manner
plaintext = []
col = 0
row = 0
for i in range(len(ciphertext)):
if row == 0: # Highest level row
direction_down = True
if row == key - 1: # Lowest level row
direction_down = False
# Begin constructing the plaintext
plaintext.append(rail[row][col])
col += 1
# Change rows based on the flag variable 'direction_down' logic
if direction_down:
row += 1
else:
row -= 1
return "".join(plaintext) # Convert the plaintext list into a singular string
#----------------------------------------------------------------------------------------------------------------------------------------------
# Main code (Performs computations and Input/Output operations)
# User input to perform encryption or decryption
user_input = input("\nWould you like to perform encryption or decryption?\nPlease Enter 'e' or 'd': ").lower() # In case user uses capital letters
isValid = True
# Check if the user input is 'e' or 'd'
if user_input not in ['e', 'd']:
print("Invalid input, please enter 'e' for encryption or 'd' for decryption.")
isValid = False
else:
# Taking user input for the key value
user_input_key = input("Enter a key to use >= 2 of type (int): ")
try: # Ensure the user can only use valid whole numbers as the key value
key = int(user_input_key)
if key < 2: # Need at least 2 rows or more in order to encrypt
print("Please enter a key a value >= 2.")
isValid = False
except ValueError:
print("Invalid key input, please enter a valid number.")
isValid = False
# This pair of Ciphertext and Plaintext can be used as input for testing purposes if desired:
# ciphertext = "TCECAYSRHSIHRSETILNTEUEIPIRNOC"
# key = 3
# plaintext = "THIS CIPHER IS CERTAINLY NOT SECURE"
if user_input == 'e' and isValid == True: # If the user chooses to encrypt data and they also have valid input
user_input_plaintext = input("\nPlease enter the plaintext to encrypt: \n")
ciphertext = encryptRailFence(user_input_plaintext, key) # Call the method for encryption
print("\nPlaintext (Original): " + user_input_plaintext)
print("Ciphertext (Generated): " + ciphertext)
print("Key Value Chosen:", key)
elif user_input == 'd' and isValid == True: # If the user chooses to decrypt data and they also have valid input
user_input_ciphertext = input("\nPlease enter the ciphertext to decrypt: \n")
plaintext = decryptRailFence(user_input_ciphertext, key) # Call the method for decryption
print("\nCiphertext (Original): " + user_input_ciphertext)
print("Plaintext (Generated): " + plaintext)
print("Key Value Chosen:", key)
else: # Will only appear if the user has invalid input data somewhere
print("\nAn error has occured, please try again.\n")