Skip to content

Commit

Permalink
Added Siam's algo's and fixed his bugs
Browse files Browse the repository at this point in the history
  • Loading branch information
Sas2k committed Jul 28, 2022
1 parent 35e70b4 commit c6f7ea0
Show file tree
Hide file tree
Showing 15 changed files with 743 additions and 233 deletions.
41 changes: 41 additions & 0 deletions src/encrypt/1_caesar_cipher.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import string
from random import randint


def caeser_encrypt(word, key):
letters = (
string.ascii_lowercase
+ string.ascii_lowercase
+ string.ascii_uppercase
+ string.ascii_uppercase
)
enc = ""
for i in word:
if i in letters:
enc += letters[(letters.index(i) + key)]
else:
enc += i

return enc


def caeser_decrypt(word, key):
letters = (
string.ascii_lowercase
+ string.ascii_lowercase
+ string.ascii_uppercase
+ string.ascii_uppercase
)
enc = ""
for i in word:
if i in letters:
enc += letters[(letters.index(i) - key)]
else:
enc += i

return enc


key = randint(1, 26)
print(caeser_encrypt("ATTACKATm4Once", key))
print(caeser_decrypt(caeser_encrypt("ATTACKATm4Once", key), key))
26 changes: 26 additions & 0 deletions src/encrypt/2_monoalpabetic_cipher.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
PTA = " abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
CTA = " qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM0123456789"


def mono_alpabetic_cipher_encrypt(pt):
ans = ""
for i in pt:
try:
ans += CTA[PTA.index(i)]
except:
ans += i
return ans


def mono_alpabetic_cipher_decrypt(pt):
ans = ""
for i in pt:
try:
ans += PTA[CTA.index(i)]
except:
ans += i
return ans


print(mono_alpabetic_cipher_encrypt("ATTACKm#4Once"))
print(mono_alpabetic_cipher_decrypt(mono_alpabetic_cipher_encrypt("ATTACKm#4Once")))
76 changes: 76 additions & 0 deletions src/encrypt/3_vigenere.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import string


def vigenere_encrypt(word, key):
key = (key * (len(word) // len(key))) + key[: len(word) % len(key)]
letters = (
string.ascii_lowercase
+ string.ascii_lowercase
+ string.ascii_uppercase
+ string.ascii_uppercase
)
ans = ""
for i in range(len(word)):
if word[i] in letters and key[i] in letters:
if word[i].isupper():
ans += letters[
(letters.index(word[i]) + letters.index(key[i])) % 26
].upper()
else:
ans += letters[
(letters.index(word[i]) + letters.index(key[i])) % 26
].lower()
else:
ans += word[i]

return ans


def vigenere_decrypt(word, key):
key = (key * (len(word) // len(key))) + key[: len(word) % len(key)]
letters = (
string.ascii_lowercase
+ string.ascii_lowercase
+ string.ascii_uppercase
+ string.ascii_uppercase
)
ans = ""
for i in range(len(word)):
if word[i] in letters and key[i] in letters:
if word[i].isupper():
ans += letters[
(letters.index(word[i]) - letters.index(key[i])) % 26
].upper()
else:
ans += letters[
(letters.index(word[i]) - letters.index(key[i])) % 26
].lower()
else:
ans += word[i]

return ans


word = "GEEKSFORGEEKS"
key = "AYUSH"
print("Original word:", word)
print("Encrypted: ", vigenere_encrypt(word, key))
print("Decrypted: ", vigenere_decrypt(vigenere_encrypt(word, key), key))

word = "GeeksForGeeks"
key = "AYUSH"
print("Original word:", word)
print("Encrypted: ", vigenere_encrypt(word, key))
print("Decrypted: ", vigenere_decrypt(vigenere_encrypt(word, key), key))

word = "Geeks4Geeks"
key = "AYUSH"
print("Original word:", word)
print("Encrypted: ", vigenere_encrypt(word, key))
print("Decrypted: ", vigenere_decrypt(vigenere_encrypt(word, key), key))

word = "Geeks#4#Geeks"
key = "AYUSH"
print("Original word:", word)
print("Encrypted: ", vigenere_encrypt(word, key))
print("Decrypted: ", vigenere_decrypt(vigenere_encrypt(word, key), key))
79 changes: 79 additions & 0 deletions src/encrypt/4_simple_transposition.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import math

key = "HACK"

def encryptMessage(msg):
cipher = ""

k_indx = 0

msg_len = float(len(msg))
msg_lst = list(msg)
key_lst = sorted(list(key))

col = len(key)

row = int(math.ceil(msg_len / col))

fill_null = int((row * col) - msg_len)
msg_lst.extend('_' * fill_null)

matrix = [msg_lst[i: i + col]
for i in range(0, len(msg_lst), col)]

for _ in range(col):
curr_idx = key.index(key_lst[k_indx])
cipher += ''.join([row[curr_idx]
for row in matrix])
k_indx += 1

return cipher

def decryptMessage(cipher):
msg = ""

k_indx = 0

msg_indx = 0
msg_len = float(len(cipher))
msg_lst = list(cipher)

col = len(key)

row = int(math.ceil(msg_len / col))

key_lst = sorted(list(key))

dec_cipher = []
for _ in range(row):
dec_cipher += [[None] * col]

for _ in range(col):
curr_idx = key.index(key_lst[k_indx])

for j in range(row):
dec_cipher[j][curr_idx] = msg_lst[msg_indx]
msg_indx += 1
k_indx += 1

try:
msg = ''.join(sum(dec_cipher, []))
except TypeError:
raise TypeError("This program cannot",
"handle repeating words.")

null_count = msg.count('_')

if null_count > 0:
return msg[: -null_count]

return msg

msg = "qwertyuiopasdfghjklzxcvbnm ,./;'[] 0987654321"

cipher = encryptMessage(msg)
print("Encrypted Message: {}".
format(cipher))

print("Decryped Message: {}".
format(decryptMessage(cipher)))
Empty file added src/encrypt/__init__.py
Empty file.
58 changes: 58 additions & 0 deletions src/encrypt/ceaser_cipher.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import string
import random


class CeaserCipher:
def encrypt(self, plain_text: str, key: int) -> str:
letters = (
string.ascii_lowercase
+ string.ascii_lowercase
+ string.ascii_uppercase
+ string.ascii_uppercase
)

cipher_text = ""
for i in plain_text:
if i in letters:
cipher_text += letters[(letters.index(i) + key)]
else:
cipher_text += i

return cipher_text

def decrypt(self, cipher_text: str, key: int) -> str:
letters = (
string.ascii_lowercase
+ string.ascii_lowercase
+ string.ascii_uppercase
+ string.ascii_uppercase
)

decrypted_text = ""
for i in cipher_text:
if i in letters:
decrypted_text += letters[(letters.rindex(i) - key)]
else:
decrypted_text += i

return decrypted_text

def genkey(self) -> int:
return random.randint(1, 26)


class CeaserCipherEncoder:
def encode_plaintext(self, plain_text: str) -> str:
return str(bytes(plain_text, "utf-8"), "cp437")

def decode_encrypted_message(self, encrypted_message: str) -> str:
return encrypted_message

def encode_encrypted_message(self, encrypted_message: str) -> str:
return encrypted_message

def decode_decrypted_message(self, decrypted_message: str) -> str:
return str(bytes(decrypted_message, "cp437"), "utf-8")

def decode_key(self, key: int) -> str:
return str(key)
56 changes: 56 additions & 0 deletions src/encrypt/encryption_facade.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
from src.encrypt.one_time_pad import OneTimePadCipher, OneTimePadEncoder
from src.encrypt.substitution_cipher import SubsitutionCipher, SubsitutionCipherEncoder
from src.encrypt.ceaser_cipher import CeaserCipher, CeaserCipherEncoder
from src.encrypt.transposition_cipher import (
TranspositionCipher,
TranspositionCipherEncoder,
)
from src.encrypt.vigenere import VigenereCipher, VigenereCipherEncoder

from typing import Dict


class CipherFacade:

encryption_schemes = {
"OneTimePad": OneTimePadCipher,
"SubstitutionCipher": SubsitutionCipher,
"CeaserCipher": CeaserCipher,
"TranspositionCipher": TranspositionCipher,
"VigenereCipher": VigenereCipher,
}

encoders = {
"OneTimePad": OneTimePadEncoder,
"SubstitutionCipher": SubsitutionCipherEncoder,
"CeaserCipher": CeaserCipherEncoder,
"TranspositionCipher": TranspositionCipherEncoder,
"VigenereCipher": VigenereCipherEncoder,
}

def __init__(self, config: Dict[str, object]) -> None:

self.cipher = CipherFacade.encryption_schemes[config["scheme"]]()
self.encoder = CipherFacade.encoders[config["scheme"]]()

if "key" in config:
self.key = config["key"]
elif "key_args" in config:
self.key = self.cipher.genkey(**config["key_args"])
else:
self.key = self.cipher.genkey()

self.config = config

def encrypt(self, plain_text: str) -> str:
encoded_plaintext = self.encoder.encode_plaintext(plain_text)
encrypted_text = self.cipher.encrypt(encoded_plaintext, self.key)
return self.encoder.decode_encrypted_message(encrypted_text)

def decrypt(self, cipher_text: str) -> str:
encoded_ciphertext = self.encoder.encode_encrypted_message(cipher_text)
decrypted_text = self.cipher.decrypt(encoded_ciphertext, self.key)
return self.encoder.decode_decrypted_message(decrypted_text)

def get_key(self):
return self.encoder.decode_key(self.key)
30 changes: 30 additions & 0 deletions src/encrypt/one_time_pad.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import secrets
import codecs


class OneTimePadCipher:
def encrypt(self, plain_text: bytes, key: bytes) -> bytes:
return bytes([p ^ k for p, k in zip(plain_text, key)])

def decrypt(self, cipher_text: bytes, key: bytes) -> bytes:
return self.encrypt(cipher_text, key)

def genkey(self, length: int) -> bytes:
return secrets.token_bytes(length)


class OneTimePadEncoder:
def encode_plaintext(self, plain_text: str) -> bytes:
return bytes(plain_text, "utf-8")

def decode_encrypted_message(self, encrypted_message: bytes) -> str:
return encrypted_message.hex()

def encode_encrypted_message(self, encrypted_message: str) -> bytes:
return codecs.decode(encrypted_message, "hex")

def decode_decrypted_message(self, decrypted_message: bytes) -> str:
return decrypted_message.hex()

def decode_key(self, key: bytes) -> str:
return key.hex()
Loading

0 comments on commit c6f7ea0

Please sign in to comment.