Skip to content

Commit 30ab1fe

Browse files
committed
add cracking affine cipher tutorial
1 parent b277253 commit 30ab1fe

File tree

4 files changed

+95
-0
lines changed

4 files changed

+95
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ This is a repository of all the tutorials of [The Python Code](https://www.thepy
5252
- [How to Lock PDFs in Python](https://thepythoncode.com/article/lock-pdfs-in-python). [(code)](ethical-hacking/pdf-locker)
5353
- [How to Create a Custom Wordlist in Python](https://thepythoncode.com/article/make-a-wordlist-generator-in-python). ([code](ethical-hacking/bruteforce-wordlist-generator))
5454
- [How to Implement the Affine Cipher in Python](https://thepythoncode.com/article/how-to-implement-affine-cipher-in-python). ([code](ethical-hacking/implement-affine-cipher))
55+
- [How to Crack the Affine Cipher in Python](https://thepythoncode.com/article/how-to-crack-the-affine-cipher-in-python). ([code](ethical-hacking/crack-affine-cipher))
5556

5657
- ### [Machine Learning](https://www.thepythoncode.com/topic/machine-learning)
5758
- ### [Natural Language Processing](https://www.thepythoncode.com/topic/nlp)
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# [How to Crack the Affine Cipher in Python](https://thepythoncode.com/article/how-to-crack-the-affine-cipher-in-python)
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
# Import the needed libraries.
2+
import string
3+
from colorama import Fore, init
4+
5+
# Initialise colorama.
6+
init()
7+
8+
9+
# Function to get Euclidean Algorithm.
10+
def extended_gcd(a, b):
11+
"""
12+
Extended Euclidean Algorithm to find the greatest common divisor
13+
and coefficients x, y such that ax + by = gcd(a, b).
14+
"""
15+
if a == 0:
16+
return (b, 0, 1)
17+
else:
18+
g, x, y = extended_gcd(b % a, a)
19+
return (g, y - (b // a) * x, x)
20+
21+
22+
# Function to get the modular Inverse
23+
def modular_inverse(a, m):
24+
"""
25+
Compute the modular multiplicative inverse of a modulo m.
26+
Raises an exception if the modular inverse does not exist.
27+
"""
28+
g, x, y = extended_gcd(a, m)
29+
if g != 1:
30+
raise Exception('Modular inverse does not exist')
31+
else:
32+
return x % m
33+
34+
35+
# Function to decrypt our message.
36+
def affine_decrypt(ciphertext, a, b):
37+
"""
38+
Decrypt a message encrypted with the Affine Cipher using
39+
the given key components a and b.
40+
"""
41+
alphabet = string.ascii_uppercase
42+
m = len(alphabet)
43+
plaintext = ''
44+
45+
# Compute the modular multiplicative inverse of a.
46+
a_inv = modular_inverse(a, m)
47+
48+
# Iterate through each character in the ciphertext.
49+
for char in ciphertext:
50+
# Check if the character is in the alphabet
51+
if char in alphabet:
52+
# If it's an alphabet letter, decrypt it.
53+
# Find the index of the character in the alphabet.
54+
c = alphabet.index(char)
55+
# Apply the decryption formula: a_inv * (c - b) mod m.
56+
p = (a_inv * (c - b)) % m
57+
# Append the decrypted character to the plaintext.
58+
plaintext += alphabet[p]
59+
else:
60+
# If the character is not in the alphabet, keep it unchanged.
61+
plaintext += char
62+
63+
# Return the decrypted plaintext.
64+
return plaintext
65+
66+
67+
# Function to peform brute force attack.
68+
def affine_brute_force(ciphertext):
69+
"""
70+
Brute-force attack to find possible keys for an Affine Cipher
71+
and print potential decryptions for manual inspection.
72+
"""
73+
alphabet = string.ascii_uppercase
74+
m = len(alphabet)
75+
76+
# Iterate through possible values for a.
77+
for a in range(1, m):
78+
# Ensure a and m are coprime.
79+
if extended_gcd(a, m)[0] == 1:
80+
# Iterate through possible values for b.
81+
for b in range(0, m):
82+
# Decrypt using the current key.
83+
decrypted_text = affine_decrypt(ciphertext, a, b)
84+
85+
# Print potential decryption for manual inspection.
86+
print(f"Key (a={a}, b={b}): {decrypted_text}")
87+
88+
89+
ciphertext = input(f"{Fore.GREEN}[?] Enter Message to decrypt: ")
90+
91+
# Perform a brute-force attack to find potential decrypted message.
92+
affine_brute_force(ciphertext)
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
colorama

0 commit comments

Comments
 (0)