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
56 changes: 28 additions & 28 deletions homework01/caesar.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,39 +2,39 @@


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
if shift < 0:
shift = 26 + shift
a = []
for i in range(len(plaintext)):
if plaintext[i].isalpha():
a.append(ord(plaintext[i]))
else:
a.append(ord(plaintext[i]) - shift)
for i in range(len(a)):
temp = a[i] + shift
if plaintext[i].isalpha():
if a[i] >= ord("a") and a[i] <= ord("z"):
# Маленькие буквы
if temp > ord("z"):
a[i] = shift - (ord("z") - a[i]) + ord("a") - 1
else:
a[i] = a[i] + shift
else:
# Большие буквы
if temp > ord("Z"):
a[i] = shift - (ord("Z") - a[i]) + ord("A") - 1
else:
a[i] = a[i] + shift
else:
a[i] = a[i] + shift
for i in range(len(a)):
ciphertext += chr(a[i])
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:
Expand Down
68 changes: 27 additions & 41 deletions homework01/rsa.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,69 +3,55 @@


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
if n == 1:
return False
for i in range(2, n - 1):
if n % i == 0:
return False
return True


def gcd(a: int, b: int) -> int:
"""
Euclid's algorithm for determining the greatest common divisor.
if a == 0 or b == 0:
return max(a, b)
max_del = 1
for i in range(1, min(a, b)):
if a % i == 0 and b % i == 0 and i > max_del:
max_del = i
return max_del

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

def extended_gcd(a: int, b: int):
if a == 0:
return (b, 0, 1)
temp = extended_gcd(b % a, a)
return (temp[0], temp[2] - (b // a) * temp[1], temp[1])

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(e: int, phi: int) -> int:
gcd_res = extended_gcd(e, phi)
if gcd_res[1] >= 0:
return gcd_res[1]
else:
return gcd_res[1] + max(e, phi)


def generate_keypair(p: int, q: int) -> tp.Tuple[tp.Tuple[int, int], tp.Tuple[int, int]]:
if not (is_prime(p) and is_prime(q)):
raise ValueError("Both numbers must be prime.")
elif p == q:
raise ValueError("p and q cannot be equal")

# n = pq
# PUT YOUR CODE HERE

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

n = p * q
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))
Expand All @@ -85,7 +71,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
82 changes: 58 additions & 24 deletions homework01/vigenere.py
Original file line number Diff line number Diff line change
@@ -1,30 +1,64 @@
def encrypt_vigenere(plaintext: str, keyword: str) -> str:
"""
Encrypts plaintext using a Vigenere cipher.

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

for i in range(len(plaintext)):
l = ord(plaintext[i])
shift = ord(keyword[i % len(keyword)]) # смещене

k = ord(keyword[i % len(keyword)]) # порядковый номер, A-Z, a-z
if k >= ord("a") and k <= ord("z"):
shift -= ord("a")
else:
shift -= ord("A")

if plaintext[i].isalpha():
if l >= ord("a") and l <= ord("z"):
temp = l + shift
if temp > ord("z"):
ciphertext += chr(shift - (ord("z") - l) + ord("a") - 1)
else:
ciphertext += chr(temp)
else:
temp = l + shift
if temp > ord("Z"):
ciphertext += chr(shift - (ord("Z") - l) + ord("A") - 1)
else:
ciphertext += chr(temp)
else:
ciphertext += plaintext[i]

return 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
ciphertexttext = ""

for i in range(len(ciphertext)):
l = ord(ciphertext[i])
shift = ord(keyword[i % len(keyword)])

k = ord(keyword[i % len(keyword)])
if k >= ord("a") and k <= ord("z"):
shift -= ord("a")
else:
shift -= ord("A")

shift = 26 - shift

if ciphertext[i].isalpha():
if l >= ord("a") and l <= ord("z"):
temp = l + shift
if temp > ord("z"):
ciphertexttext += chr(shift - (ord("z") - l) + ord("a") - 1)
else:
ciphertexttext += chr(temp)
else:
temp = l + shift
if temp > ord("Z"):
ciphertexttext += chr(shift - (ord("Z") - l) + ord("A") - 1)
else:
ciphertexttext += chr(temp)
else:
ciphertexttext += ciphertext[i]

return ciphertexttext