Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 8 additions & 22 deletions homework01/caesar.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import typing as tp


def encrypt_caesar(plaintext: str, shift: int = 3) -> str:
"""
Encrypts plaintext using a Caesar cipher.
Expand All @@ -14,24 +15,17 @@ def encrypt_caesar(plaintext: str, shift: int = 3) -> str:
''
"""
ciphertext = ""

for i in plaintext:
if 65 <= ord(i) <= 122:
if i.isalpha():
if i.isupper():
if ord(i) >= 87:
ciphertext += chr(65 + (ord(i) + shift) % 91)
else:
ciphertext += chr(ord(i) + shift)
ciphertext += chr(((ord(i) - ord("A")) + shift) % 26 + ord("A"))
else:
if ord(i) >= 119:
ciphertext += chr(97 + (ord(i) + shift) % 123)
else:
ciphertext += chr(ord(i) + shift)
ciphertext += chr(((ord(i) - ord("a")) + shift) % 26 + ord("a"))
else:
ciphertext += i

return ciphertext


def decrypt_caesar(ciphertext: str, shift: int = 3) -> str:
"""
Decrypts a ciphertext using a Caesar cipher.
Expand All @@ -46,22 +40,14 @@ def decrypt_caesar(ciphertext: str, shift: int = 3) -> str:
''
"""
plaintext = ""

for i in ciphertext:
if 65 <= ord(i) <= 122:
if i.isalpha():
if i.isupper():
if ord(i) <= 68:
plaintext += chr(90 - (2 - (ord(i) % 65)))
else:
plaintext += chr(ord(i) - shift)
plaintext += chr(((ord(i) - ord("A")) - shift) % 26 + ord("A"))
else:
if ord(i) <= 99:
plaintext += chr(122 - (2 - (ord(i) % 97)))
else:
plaintext += chr(ord(i) - shift)
plaintext += chr(((ord(i) - ord("a")) - shift) % 26 + ord("a"))
else:
plaintext += i

return plaintext


Expand Down
58 changes: 10 additions & 48 deletions homework01/rsa.py
Original file line number Diff line number Diff line change
@@ -1,36 +1,19 @@
import random
import typing as tp


def is_prime(n: int) -> bool:
"""
Tests to see if a number is prime.

>>> is_prime(2)
True
>>> is_prime(11)
True
>>> is_prime(8)
False
"""
k = 0
for i in range(2, n):
if n <= 1:
return False
flag = True
for i in range(2, n // 2 + 1):
if n % i == 0:
k = 1
if k > 0:
return False

return True
flag = False
break
return flag


def gcd(a: int, b: int) -> int:
"""
Euclid's algorithm for determining the greatest common divisor.

>>> gcd(12, 15)
3
>>> gcd(3, 7)
1
"""
while a != 0 and b != 0:
if a >= b:
a %= b
Expand All @@ -40,13 +23,6 @@ def gcd(a: int, b: int) -> int:


def multiplicative_inverse(e: int, phi: int) -> int:
"""
Euclid's extended algorithm for finding the multiplicative
inverse of two numbers.

>>> multiplicative_inverse(7, 40)
23
"""
return pow(e, -1, phi)


Expand All @@ -57,44 +33,30 @@ def generate_keypair(p: int, q: int) -> tp.Tuple[tp.Tuple[int, int], tp.Tuple[in
raise ValueError("p and q cannot be equal")

n = p * q
# PUT YOUR CODE HERE

phi = (p-1) * (q-1)
# PUT YOUR CODE HERE
phi = (p - 1) * (q - 1)

# Choose an integer e such that e and phi(n) are coprime
e = random.randrange(1, phi)

# Use Euclid's Algorithm to verify that e and phi(n) are coprime
g = gcd(e, phi)
while g != 1:
e = random.randrange(1, phi)
g = gcd(e, phi)

# Use Extended Euclid's Algorithm to generate the private key
d = multiplicative_inverse(e, phi)

# Return public and private keypair
# Public key is (e, n) and private key is (d, n)
return ((e, n), (d, n))


def encrypt(pk: tp.Tuple[int, int], plaintext: str) -> tp.List[int]:
# Unpack the key into it's components
key, n = pk
# Convert each letter in the plaintext to numbers based on
# the character using a^b mod m
cipher = [(ord(char) ** key) % n for char in plaintext]
# Return the array of bytes
return cipher


def decrypt(pk: tp.Tuple[int, int], ciphertext: tp.List[int]) -> str:
# Unpack the key into its components
key, n = pk
# Generate the plaintext based on the ciphertext and key using a^b mod m
plain = [chr((char ** key) % n) for char in ciphertext]
# Return the array of bytes as a string
plain = [chr((char**key) % n) for char in ciphertext]
return "".join(plain)


Expand Down
55 changes: 28 additions & 27 deletions homework01/vigenere.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,24 @@ def encrypt_vigenere(plaintext: str, keyword: str) -> str:
'LXFOPVEFRNHR'
"""
ciphertext = ""

key_length = len(keyword)
key_int = [ord(i) for i in keyword]
plaintext_int = [ord(i) for i in plaintext]

for i in range(len(plaintext_int)):
if plaintext_int[i] == 32:
plaintext += " "
elif plaintext[i].isupper():
value = (plaintext_int[i] + key_int[i % key_length]) % 26
ciphertext += chr(value + 65)
for i in range(len(plaintext)):
if plaintext[i].isalpha():
if plaintext[i].isupper():
ciphertext += chr(
(ord(plaintext[i]) - 2 * ord("A") + ord(keyword[i % len(keyword)].upper()))
% 26
% 26
+ ord("A")
)
else:
ciphertext += chr(
(ord(plaintext[i]) - 2 * ord("a") + ord(keyword[i % len(keyword)].lower()))
% 26
% 26
+ ord("a")
)
else:
value = (plaintext_int[i] + key_int[i % key_length] - 64) % 26
ciphertext += chr(value + 97)

ciphertext += plaintext[i]
return ciphertext


Expand All @@ -40,18 +43,16 @@ def decrypt_vigenere(ciphertext: str, keyword: str) -> str:
'ATTACKATDAWN'
"""
plaintext = ""
key_length = len(keyword)
key_int = [ord(i) for i in keyword]
ciphertext_int = [ord(i) for i in ciphertext]

for i in range(len(ciphertext_int)):
if ciphertext_int[i] == 32:
plaintext += " "
elif chr(ciphertext_int[i]).isupper():
value = (ciphertext_int[i] - key_int[i % key_length]) % 26
plaintext += chr(value + 65)
for i in range(len(ciphertext)):
if ciphertext[i].isalpha():
if ciphertext[i].isupper():
plaintext += chr(
(ord(ciphertext[i]) - ord(keyword[i % len(keyword)].upper())) % 26 + ord("A")
)
else:
plaintext += chr(
(ord(ciphertext[i]) - ord(keyword[i % len(keyword)].lower())) % 26 + ord("a")
)
else:
value = (ciphertext_int[i] - key_int[i % key_length]) % 26
plaintext += chr(value + 97)

plaintext += ciphertext[i]
return plaintext