50 lines
1.3 KiB
Python
50 lines
1.3 KiB
Python
import numpy as np
|
|
|
|
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("Plaintext: ")
|
|
hk = input("Hill Key: ")
|
|
ctext = hill_en(ptext, hk)
|
|
print(f"Ciphertext: {ctext}")
|
|
print(f"Decrypted: {hill_de(ctext, hk)}")
|
|
|
|
if __name__ == '__main__':
|
|
main()
|