Modified Lab 1 IS
This commit is contained in:
parent
fdc634b589
commit
933a52b3a8
8 changed files with 166 additions and 384 deletions
|
@ -1,6 +1,7 @@
|
|||
## ptext = plaintext
|
||||
## ctext = ciphertext
|
||||
## mk = multiplicative key
|
||||
## ak = additive key
|
||||
from collections import defaultdict
|
||||
|
||||
def add_cipher_en(ptext, ak):
|
||||
result = ""
|
||||
|
@ -76,6 +77,10 @@ def affine_de(ctext, ak, mk):
|
|||
result += chr((((ord(ch) - 97 - ak) * inverse) % 26) + 97)
|
||||
return result
|
||||
|
||||
def mult_inverse(mk):
|
||||
inverse = pow(mk, -1, 26)
|
||||
return inverse
|
||||
|
||||
def operator(argument,ptext,ak,mk):
|
||||
match argument:
|
||||
case '1':
|
||||
|
@ -91,6 +96,7 @@ def operator(argument,ptext,ak,mk):
|
|||
print("Multiplicative Key: ", mk)
|
||||
ctext = mult_cipher_en(ptext, mk)
|
||||
print("Ciphertext: ", ctext)
|
||||
print("Multiplicative Inverse: ", mult_inverse(mk))
|
||||
print("Decrypted Text: ", mult_cipher_de(ctext, mk))
|
||||
case '3':
|
||||
print("Affine Cipher")
|
||||
|
@ -99,6 +105,7 @@ def operator(argument,ptext,ak,mk):
|
|||
print("Multiplicative Key: ", mk)
|
||||
ctext = affine_en(ptext, ak, mk)
|
||||
print("Ciphertext: ", ctext)
|
||||
print("Affine Inverse: ", mult_inverse(mk))
|
||||
print("Decrypted Text: ", affine_de(ctext, ak, mk))
|
||||
case '4':
|
||||
print("Goodbye")
|
||||
|
@ -122,6 +129,5 @@ def main():
|
|||
op = input("Enter your choice of operation: ")
|
||||
operator(op, ptext, ak, mk)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
|
|
@ -1,18 +1,50 @@
|
|||
def hill_en(ptext,hk):
|
||||
import numpy as np
|
||||
|
||||
def hill_de(ptext,hk):
|
||||
def hill_en(ptext, hk):
|
||||
# all letters to uppercase
|
||||
ptext = ''.join(c.upper() for c in ptext if c.isalpha())
|
||||
|
||||
# matrix size
|
||||
n = int(len(hk)**0.5)
|
||||
|
||||
# key matrix
|
||||
key = np.array([ord(c) - 65 for c in hk]).reshape(n, n)
|
||||
|
||||
# padding
|
||||
ptext += 'X' * (-len(ptext) % n)
|
||||
|
||||
# block operation
|
||||
result = ""
|
||||
for i in range(0, len(ptext), n):
|
||||
block = np.array([ord(c) - 65 for c in ptext[i:i+n]])
|
||||
encrypted_block = (key @ block) % 26
|
||||
result += ''.join(chr(val + 65) for val in encrypted_block)
|
||||
|
||||
return result
|
||||
|
||||
def hill_de(ctext, hk):
|
||||
# matrix size
|
||||
n = int(len(hk)**0.5)
|
||||
|
||||
# key matrix and its inverse
|
||||
key = np.array([ord(c) - 65 for c in hk]).reshape(n, n)
|
||||
inv_key = np.linalg.inv(key).astype(int) % 26
|
||||
|
||||
# block operation
|
||||
result = ""
|
||||
for i in range(0, len(ctext), n):
|
||||
block = np.array([ord(c) - 65 for c in ctext[i:i+n]])
|
||||
decrypted_block = (inv_key @ block) % 26
|
||||
result += ''.join(chr(val + 65) for val in decrypted_block)
|
||||
|
||||
return result
|
||||
|
||||
def main():
|
||||
ptext = input("Kindly enter your desired plaintext: ")
|
||||
hk = input("Kindly enter the Hill Key: ")
|
||||
|
||||
print("Welcome to the Hill cipher.")
|
||||
print("Plaintext: ", ptext)
|
||||
print("Hill Key: ", hk)
|
||||
ptext = input("Plaintext: ")
|
||||
hk = input("Hill Key: ")
|
||||
ctext = hill_en(ptext, hk)
|
||||
print("Ciphertext: ", ctext)
|
||||
decrypted_text = hill_de(ctext, hk)
|
||||
print("Decrypted Text: ", decrypted_text)
|
||||
print(f"Ciphertext: {ctext}")
|
||||
print(f"Decrypted: {hill_de(ctext, hk)}")
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
main()
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
def main():
|
||||
shift = (ord('C') - ord('y')) % 26
|
||||
|
||||
ctext = "XVIEWYWI"
|
||||
plaintext = ""
|
||||
|
||||
for char in ctext:
|
||||
if char.isalpha():
|
||||
shifted = ord(char.lower()) - shift
|
||||
if shifted < ord('a'):
|
||||
shifted += 26
|
||||
plaintext += chr(shifted)
|
||||
else:
|
||||
plaintext += char
|
||||
|
||||
print(f"Attack type: Known plaintext attack")
|
||||
print(f"Ciphertext: {ctext}")
|
||||
print(f"Decrypted: {plaintext}")
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
|
@ -0,0 +1,47 @@
|
|||
def main():
|
||||
# Affine cipher: E(x) = (ax + b) mod 26
|
||||
# Given: "ab" -> "GL"
|
||||
# a=0, b=1 -> G=6, L=11
|
||||
# So: 6 = (a*0 + b) mod 26 -> b = 6
|
||||
# And: 11 = (a*1 + b) mod 26 -> 11 = (a + 6) mod 26 -> a = 5
|
||||
|
||||
ciphertext = "XPALASXYFGFUKPXUSOGEUTKCDGEXANMGNVS"
|
||||
|
||||
# Try all possible values of a and b for affine cipher
|
||||
for a in range(1, 26):
|
||||
# a must be coprime to 26
|
||||
if gcd(a, 26) != 1:
|
||||
continue
|
||||
|
||||
for b in range(26):
|
||||
# Check if this key produces "ab" -> "GL"
|
||||
if (a * 0 + b) % 26 == 6 and (a * 1 + b) % 26 == 11:
|
||||
# Found the key, now decrypt the message
|
||||
a_inv = mod_inverse(a, 26)
|
||||
decrypted = ""
|
||||
for char in ciphertext:
|
||||
if char.isalpha():
|
||||
y = ord(char.upper()) - ord('A')
|
||||
x = (a_inv * (y - b)) % 26
|
||||
decrypted += chr(x + ord('A'))
|
||||
else:
|
||||
decrypted += char
|
||||
|
||||
print(f"Key found: a={a}, b={b}")
|
||||
print(f"Ciphertext: {ciphertext}")
|
||||
print(f"Decrypted: {decrypted}")
|
||||
return
|
||||
|
||||
def gcd(a, b):
|
||||
while b:
|
||||
a, b = b, a % b
|
||||
return a
|
||||
|
||||
def mod_inverse(a, m):
|
||||
for i in range(1, m):
|
||||
if (a * i) % m == 1:
|
||||
return i
|
||||
return None
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
Loading…
Add table
Add a link
Reference in a new issue