HP


CEASAR CIPHER

def encrypt(text, shift):
result = ""

for char in text:
    if char.isalpha():
        shift_base = ord('A') if char.isupper() else ord('a')
        result += chr((ord(char) - shift_base + shift) % 26 + shift_base)
    elif char.isdigit():
        result += str((int(char) + shift) % 10)
    else:
        result += char
return result

def decrypt(text, shift):
return encrypt(text, -shift)

Take input from user

message = input("Enter the message: ")
shift = int(input("Enter the shift value: "))

Perform encryption and decryption

encrypted = encrypt(message, shift)
decrypted = decrypt(encrypted, shift)

print("Original: ", message)
print("Encrypted: ", encrypted)
print("Decrypted: ", decrypted)

.....................
PLAYFAIR CIPHER

def playfair_encrypt(msg, key):
key = ''.join(dict.fromkeys(key.upper().replace('J', 'I')))
alpha = "ABCDEFGHIKLMNOPQRSTUVWXYZ"
for c in alpha:
if c not in key:
key += c
m = [list(key[i:i+5]) for i in range(0, 25, 5)]

def pos(c):
    for i in range(5):
        for j in range(5):
            if m[i][j] == c:
                return i, j

msg = msg.upper().replace("J", "I").replace(" ", "")
pairs = []
i = 0
while i < len(msg):
    a = msg[i]
    b = ''
    if i + 1 < len(msg):
        b = msg[i + 1]
        if a == b:
            b = 'X'
            i += 1
        else:
            i += 2
    else:
        b = 'X'
        i += 1
    pairs.append(a + b)

res = ""
for a, b in pairs:
    x1, y1 = pos(a)
    x2, y2 = pos(b)
    if x1 == x2:
        res += m[x1][(y1+1)%5] + m[x2][(y2+1)%5]
    elif y1 == y2:
        res += m[(x1+1)%5][y1] + m[(x2+1)%5][y2]
    else:
        res += m[x1][y2] + m[x2][y1]

return ' '.join(res[i:i+4] for i in range(0, len(res), 4))

def playfair_decrypt(cipher, key):
key = ''.join(dict.fromkeys(key.upper().replace('J', 'I')))
alpha = "ABCDEFGHIKLMNOPQRSTUVWXYZ"
for c in alpha:
if c not in key:
key += c
m = [list(key[i:i+5]) for i in range(0, 25, 5)]

def pos(c):
    for i in range(5):
        for j in range(5):
            if m[i][j] == c:
                return i, j

cipher = cipher.replace(" ", "")
pairs = [cipher[i:i+2] for i in range(0, len(cipher), 2)]

res = ""
for a, b in pairs:
    x1, y1 = pos(a)
    x2, y2 = pos(b)
    if x1 == x2:
        res += m[x1][(y1-1)%5] + m[x2][(y2-1)%5]
    elif y1 == y2:
        res += m[(x1-1)%5][y1] + m[(x2-1)%5][y2]
    else:
        res += m[x1][y2] + m[x2][y1]

# Remove filler 'X' inserted between same letters or at the end
cleaned = ""
i = 0
while i < len(res):
    cleaned += res[i]
    if (i+2 < len(res) and res[i] == res[i+2] and res[i+1] == 'X'):
        i += 2  # skip the filler 'X'
    else:
        i += 1
if cleaned.endswith('X'):
    cleaned = cleaned[:-1]

return cleaned

🔽 Taking input from user

message = input("Enter the message to encrypt: ")
key = input("Enter the key: ")

🔐 Encrypt and display

encrypted = playfair_encrypt(message, key)
print("Encrypted message:", encrypted)

🔓 Decrypt and display

decrypted = playfair_decrypt(encrypted, key)
print("Decrypted message:", decrypted)

..................................
HILL CIHPER

import numpy as np

Converts letter to number (A=0 to Z=25)

def letter_to_num(letter):
return ord(letter.upper()) - ord('A')

Converts number to letter (0=A to 25=Z)

def num_to_letter(num):
return chr(int(num) + ord('A'))

Create 2-character vectors from input text

def create_vector(text, size):
text = text.upper().replace(" ", "")
while len(text) % size != 0:
text += 'X' # Padding if not divisible
vectors = []
for i in range(0, len(text), size):
vectors.append([letter_to_num(char) for char in text[i:i+size]])
return vectors

Encrypt text using Hill Cipher

def encrypt(plaintext, key_matrix):
size = key_matrix.shape[0]
vectors = create_vector(plaintext, size)
encrypted = ''
for vec in vectors:
result = np.dot(key_matrix, vec) % 26
encrypted += ''.join([num_to_letter(num) for num in result])
return encrypted

Modular inverse function

def mod_inverse(a, m):
for i in range(m):
if (a * i) % m == 1:
return i
raise ValueError("No modular inverse exists.")

Decrypt ciphertext using Hill Cipher

def decrypt(ciphertext, key_matrix):
size = key_matrix.shape[0]
det = int(round(np.linalg.det(key_matrix)))
det_inv = mod_inverse(det % 26, 26)

# Calculate adjugate matrix
key_matrix_inv = np.linalg.inv(key_matrix)
adj_matrix = np.round(det * key_matrix_inv).astype(int) % 26
inverse_matrix = (det_inv * adj_matrix) % 26

vectors = create_vector(ciphertext, size)
decrypted = ''
for vec in vectors:
    result = np.dot(inverse_matrix, vec) % 26
    decrypted += ''.join([num_to_letter(num) for num in result])
return decrypted

Main function

def main():
print("===== Hill Cipher =====")
plaintext = input("Enter plaintext (A-Z only): ").upper()

# Key matrix input (2x2)
print("Enter 2x2 key matrix row-wise (4 integers A-Z => 0-25):")
key_elements = []
for i in range(4):
    key_elements.append(int(input(f"Element {i+1}: ")))
key_matrix = np.array(key_elements).reshape(2, 2)

try:
    ciphertext = encrypt(plaintext, key_matrix)
    print("Encrypted Text:", ciphertext)

    decrypted = decrypt(ciphertext, key_matrix)
    print("Decrypted Text:", decrypted)
except Exception as e:
    print("Error:", e)

Run the program

main()

..............................
RAIL FENCE

def encrypt_rail_fence(text, key):
rail = [['\n' for _ in range(len(text))]
for _ in range(key)]

dir_down = False
row, col = 0, 0

for char in text:
    if row == 0 or row == key - 1:
        dir_down = not dir_down

    rail[row][col] = char
    col += 1

    row += 1 if dir_down else -1

result = ''
for r in rail:
    result += ''.join(r).replace('\n', '')
return result

def decrypt_rail_fence(cipher, key):
rail = [['\n' for _ in range(len(cipher))]
for _ in range(key)]

dir_down = None
row, col = 0, 0

for i in range(len(cipher)):
    if row == 0:
        dir_down = True
    if row == key - 1:
        dir_down = False

    rail[row][col] = '*'
    col += 1

    row += 1 if dir_down else -1

index = 0
for i in range(key):
    for j in range(len(cipher)):
        if rail[i][j] == '*' and index < len(cipher):
            rail[i][j] = cipher[index]
            index += 1

result = ''
row, col = 0, 0
for i in range(len(cipher)):
    if row == 0:
        dir_down = True
    if row == key - 1:
        dir_down = False

    result += rail[row][col]
    col += 1

    row += 1 if dir_down else -1

return result

Main Program

if name == "main":
print("Rail Fence Cipher\n")

plain_text = input("Enter the plain text: ").replace(" ", "").upper()
key = int(input("Enter the number of rails: "))

encrypted = encrypt_rail_fence(plain_text, key)
print("\nEncrypted Text:", encrypted)

decrypted = decrypt_rail_fence(encrypted, key)
print("Decrypted Text:", decrypted)

.......................................
SINGLE AND DOUBLE

import math

def encrypt_message(message, key):
num_columns = len(key)
num_rows = math.ceil(len(message) / num_columns)
padded_len = num_rows * num_columns
padded_message = message.ljust(padded_len, 'X') # Padding with 'X' if needed

# Create a grid
grid = [''] * num_columns
for idx, char in enumerate(padded_message):
    col = idx % num_columns
    grid[col] += char

# Reorder columns according to key
key_order = sorted(list(enumerate(key)), key=lambda x: x[1])
ciphertext = ''
for col_idx, _ in key_order:
    ciphertext += grid[col_idx]

return ciphertext

def decrypt_message(ciphertext, key):
num_columns = len(key)
num_rows = math.ceil(len(ciphertext) / num_columns)

key_order = sorted(list(enumerate(key)), key=lambda x: x[1])
col_lengths = [num_rows] * num_columns

grid = [''] * num_columns
start = 0

for idx, (orig_pos, _) in enumerate(key_order):
    grid[orig_pos] = ciphertext[start:start+col_lengths[orig_pos]]
    start += col_lengths[orig_pos]

plaintext = ''
for i in range(num_rows):
    for col in range(num_columns):
        if i < len(grid[col]):
            plaintext += grid[col][i]

return plaintext.rstrip('X')  # Remove padding

Get user input

message = input("Enter the message to encrypt: ").replace(" ", "").upper()
key_input = input("Enter a numeric key (e.g., 4312567): ")

Convert key into list of characters (string version)

key = list(key_input)

Encrypt

cipher = encrypt_message(message, key)
print("Encrypted Message:", cipher)

Decrypt

plain = decrypt_message(cipher, key)
print("Decrypted Message:", plain)

.........................
import math

def encrypt_columnar(message, key):
num_columns = len(key)
num_rows = math.ceil(len(message) / num_columns)
padded_len = num_rows * num_columns
padded_message = message.ljust(padded_len, 'X') # Padding with 'X'

# Create column-wise grid
grid = [''] * num_columns
for idx, char in enumerate(padded_message):
    col = idx % num_columns
    grid[col] += char

# Reorder columns using the key
key_order = sorted(list(enumerate(key)), key=lambda x: x[1])
ciphertext = ''
for col_idx, _ in key_order:
    ciphertext += grid[col_idx]

return ciphertext

def decrypt_columnar(ciphertext, key):
num_columns = len(key)
num_rows = math.ceil(len(ciphertext) / num_columns)

key_order = sorted(list(enumerate(key)), key=lambda x: x[1])
col_lengths = [num_rows] * num_columns

grid = [''] * num_columns
start = 0
for idx, (orig_pos, _) in enumerate(key_order):
    grid[orig_pos] = ciphertext[start:start+col_lengths[orig_pos]]
    start += col_lengths[orig_pos]

plaintext = ''
for i in range(num_rows):
    for col in range(num_columns):
        if i < len(grid[col]):
            plaintext += grid[col][i]

return plaintext.rstrip('X')

Get user input

message = input("Enter the message to encrypt: ").replace(" ", "").upper()
key1 = list(input("Enter the first key (e.g., 4312567): "))
key2 = list(input("Enter the second key (e.g., 3214): "))

Double encryption

cipher_once = encrypt_columnar(message, key1)
cipher_twice = encrypt_columnar(cipher_once, key2)
print("\nEncrypted Message (Double Columnar):", cipher_twice)

Double decryption

decrypt_once = decrypt_columnar(cipher_twice, key2)
decrypt_twice = decrypt_columnar(decrypt_once, key1)
print("Decrypted Message:", decrypt_twice)

.............................
AES

from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
from Crypto.Random import get_random_bytes

Take 16-character key input from user

key_input = input("Enter a 16-character secret key: ")
while len(key_input) != 16:
print("❌ Key must be exactly 16 characters long for AES-128.")
key_input = input("Enter a 16-character secret key: ")

key = key_input.encode() # Convert string to bytes

Take message input from user

user_input = input("Enter a message to encrypt: ")
message = user_input.encode() # Convert string to bytes

Pad message to match AES block size

padded_msg = pad(message, AES.block_size)

Create AES cipher and encrypt

cipher = AES.new(key, AES.MODE_ECB)
ciphertext = cipher.encrypt(padded_msg)
print("🔐 Encrypted:", ciphertext)

Decrypt

decipher = AES.new(key, AES.MODE_ECB)
decrypted = unpad(decipher.decrypt(ciphertext), AES.block_size)
print("🔓 Decrypted:", decrypted.decode())

..........................
def encrypt_locker_code(text, shift=4):
result = ""
for char in text:
if char.isalpha():
shift_base = ord('A') if char.isupper() else ord('a')
# Left shift is achieved by subtracting
result += chr((ord(char) - shift_base - shift) % 26 + shift_base)
elif char.isdigit():
result += str((int(char) - shift) % 10)
else:
result += char # Leave other characters unchanged
return result

Take input from the user

locker_code = input("Enter Locker Code to encrypt (e.g. LOCKER123): ")

Encrypt the input

encrypted_code = encrypt_locker_code(locker_code)

Show result

print("Encrypted Locker Code:", encrypted_code)

..................................
import numpy as np

Converts letter to number (A=0 to Z=25)

def letter_to_num(letter):
return ord(letter.upper()) - ord('A')

Converts number to letter (0=A to 25=Z)

def num_to_letter(num):
return chr(int(num) + ord('A'))

Create 3-character vectors from input text

def create_vector(text, size):
text = text.upper().replace(" ", "")
while len(text) % size != 0:
text += 'X' # Padding with 'X' to make it divisible
vectors = []
for i in range(0, len(text), size):
vectors.append([letter_to_num(char) for char in text[i:i+size]])
return vectors

Encrypt text using Hill Cipher

def encrypt(plaintext, key_matrix):
size = key_matrix.shape[0]
vectors = create_vector(plaintext, size)
encrypted = ''
for vec in vectors:
result = np.dot(key_matrix, vec) % 26
encrypted += ''.join([num_to_letter(num) for num in result])
return encrypted

Modular inverse

def mod_inverse(a, m):
for i in range(m):
if (a * i) % m == 1:
return i
raise ValueError("No modular inverse exists for determinant.")

Decrypt ciphertext using Hill Cipher

def decrypt(ciphertext, key_matrix):
size = key_matrix.shape[0]
det = int(round(np.linalg.det(key_matrix))) % 26
det_inv = mod_inverse(det, 26)

# Inverse matrix calculation
key_matrix_inv = np.linalg.inv(key_matrix)
adj_matrix = np.round(det * key_matrix_inv).astype(int) % 26
inverse_matrix = (det_inv * adj_matrix) % 26

vectors = create_vector(ciphertext, size)
decrypted = ''
for vec in vectors:
    result = np.dot(inverse_matrix, vec) % 26
    decrypted += ''.join([num_to_letter(num) for num in result])
return decrypted

Main function

def main():
print("===== Hill Cipher (3x3) =====")
plaintext = input("Enter plaintext (A-Z only): ").upper()

# Key matrix input (3x3 = 9 values)
print("Enter 3x3 key matrix row-wise (9 integers from A-Z => 0-25):")
key_elements = []
for i in range(9):
    key_elements.append(int(input(f"Element {i+1}: ")))
key_matrix = np.array(key_elements).reshape(3, 3)

try:
    ciphertext = encrypt(plaintext, key_matrix)
    print("Encrypted Text:", ciphertext)

    decrypted = decrypt(ciphertext, key_matrix)
    print("Decrypted Text:", decrypted)
except Exception as e:
    print("Error:", e)

Run the program

main()