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
2 changes: 1 addition & 1 deletion homework00/hello.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
def get_greeting(name: str) -> str:
pass
return f"Hello, {name}!"


if __name__ == "__main__":
Expand Down
46 changes: 14 additions & 32 deletions homework01/caesar.py
Original file line number Diff line number Diff line change
@@ -1,46 +1,28 @@
import typing as tp
from string import ascii_lowercase as lower
from string import ascii_uppercase as upper


def encrypt_caesar(plaintext: str, shift: int = 3) -> str:
"""
Encrypts plaintext using a Caesar cipher.

>>> encrypt_caesar("PYTHON")
'SBWKRQ'
>>> encrypt_caesar("python")
'sbwkrq'
>>> encrypt_caesar("Python3.6")
'Sbwkrq3.6'
>>> encrypt_caesar("")
''
"""
ciphertext = ""
# PUT YOUR CODE HERE
for char in plaintext:
if char.isalpha():
if char.islower():
char = lower[(lower.index(char) + shift) % 26]
else:
char = upper[(upper.index(char) + shift) % 26]
ciphertext += char
return ciphertext


def decrypt_caesar(ciphertext: str, shift: int = 3) -> str:
"""
Decrypts a ciphertext using a Caesar cipher.

>>> decrypt_caesar("SBWKRQ")
'PYTHON'
>>> decrypt_caesar("sbwkrq")
'python'
>>> decrypt_caesar("Sbwkrq3.6")
'Python3.6'
>>> decrypt_caesar("")
''
"""
plaintext = ""
# PUT YOUR CODE HERE
return plaintext
return encrypt_caesar(ciphertext, -shift)


def caesar_breaker_brute_force(ciphertext: str, dictionary: tp.Set[str]) -> int:
"""
Brute force breaking a Caesar cipher.
"""
best_shift = 0
# PUT YOUR CODE HERE
for shift in range(26):
decrypted_msg = decrypt_caesar(ciphertext, shift)
if decrypted_msg in dictionary:
best_shift = shift
return best_shift
55 changes: 22 additions & 33 deletions homework01/rsa.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,43 +3,32 @@


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
"""
# PUT YOUR CODE HERE
pass
for div in range(2, int(n**0.5) + 1):
if n % div == 0:
return False
return n != 1


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

>>> gcd(12, 15)
3
>>> gcd(3, 7)
1
"""
# PUT YOUR CODE HERE
pass

def gcdex(a, b):
if b == 0:
return a, 1, 0
else:
d, x, y = gcdex(b, a % b)
return d, y, x - y * (a // b)

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
"""
# PUT YOUR CODE HERE
pass
def multiplicative_inverse(a: int, n: int) -> int:
d, x, y = gcdex(a, n)
if d == 1:
return (x % n + n) % n
else:
return 0


def generate_keypair(p: int, q: int) -> tp.Tuple[tp.Tuple[int, int], tp.Tuple[int, int]]:
Expand All @@ -49,10 +38,10 @@ 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 = pq
# PUT YOUR CODE HERE
n = p * q

# 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)
Expand Down Expand Up @@ -85,7 +74,7 @@ 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]
plain = [chr((char**key) % n) for char in ciphertext]
# Return the array of bytes as a string
return "".join(plain)

Expand Down
40 changes: 14 additions & 26 deletions homework01/vigenere.py
Original file line number Diff line number Diff line change
@@ -1,30 +1,18 @@
def encrypt_vigenere(plaintext: str, keyword: str) -> str:
"""
Encrypts plaintext using a Vigenere cipher.
from caesar import decrypt_caesar, encrypt_caesar

>>> encrypt_vigenere("PYTHON", "A")
'PYTHON'
>>> encrypt_vigenere("python", "a")
'python'
>>> encrypt_vigenere("ATTACKATDAWN", "LEMON")
'LXFOPVEFRNHR'
"""
ciphertext = ""
# PUT YOUR CODE HERE
return ciphertext

def encrypt_vigenere(plaintext: str, keyword: str, encode: bool = True) -> str:
ciphertext = []
for index, char in enumerate(plaintext.lower()):
shift = ord(keyword[index % len(keyword)].lower()) - 97
if encode:
ciphertext.append(encrypt_caesar(char, shift))
else:
ciphertext.append(decrypt_caesar(char, shift))
if plaintext[index].isupper():
ciphertext[-1] = ciphertext[-1].upper()
return "".join(ciphertext)

def decrypt_vigenere(ciphertext: str, keyword: str) -> str:
"""
Decrypts a ciphertext using a Vigenere cipher.

>>> decrypt_vigenere("PYTHON", "A")
'PYTHON'
>>> decrypt_vigenere("python", "a")
'python'
>>> decrypt_vigenere("LXFOPVEFRNHR", "LEMON")
'ATTACKATDAWN'
"""
plaintext = ""
# PUT YOUR CODE HERE
return plaintext
def decrypt_vigenere(ciphertext: str, keyword: str) -> str:
return encrypt_vigenere(ciphertext, keyword, encode=False)