Skip to content

Commit 7ab1902

Browse files
Added the rc4.py
1 parent 93f50dd commit 7ab1902

1 file changed

Lines changed: 65 additions & 34 deletions

File tree

ciphers/rc4.py

Lines changed: 65 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -2,56 +2,87 @@
22

33
class RC4:
44
def __init__(self, key: bytes):
5-
self.key=key
6-
self.s=self._ksa(key)
5+
self.key = key
6+
self.s = self._ksa(key)
77

88
def _ksa(self, key: bytes) -> List[int]:
9-
"""Key Scheduling Algorithm (KSA)"""
10-
key_length=len(key)
11-
s=list(range(256))
12-
j=0
9+
"""
10+
Key Scheduling Algorithm (KSA)
11+
12+
>>> rc4 = RC4(b"SecretKey")
13+
>>> len(rc4._ksa(b"SecretKey"))
14+
256
15+
"""
16+
key_length = len(key)
17+
s = list(range(256))
18+
j = 0
1319
for i in range(256):
14-
j=(j+s[i]+key[i%key_length])%256
15-
s[i],s[j]=s[j],s[i]
20+
j = (j + s[i] + key[i % key_length]) % 256
21+
s[i], s[j] = s[j], s[i]
1622
return s
1723

1824
def _prga(self) -> int:
19-
"""Pseudo-Random Generation Algorithm (PRGA)"""
20-
i=0
21-
j=0
25+
"""
26+
Pseudo-Random Generation Algorithm (PRGA)
27+
28+
>>> rc4 = RC4(b"SecretKey")
29+
>>> prga = rc4._prga()
30+
>>> isinstance(next(prga), int)
31+
True
32+
"""
33+
i = 0
34+
j = 0
2235
while True:
23-
i=(i+1)%256
24-
j=(j+self.s[i])%256
25-
self.s[i],self.s[j]=self.s[j],self.s[i]
26-
yield self.s[(self.s[i]+self.s[j])%256]
36+
i = (i + 1) % 256
37+
j = (j + self.s[i]) % 256
38+
self.s[i], self.s[j] = self.s[j], self.s[i]
39+
yield self.s[(self.s[i] + self.s[j]) % 256]
2740

2841
def _reset_state(self):
2942
"""Reset state for each encryption/decryption."""
30-
self.s=self._ksa(self.key)
43+
self.s = self._ksa(self.key)
3144

32-
def encrypt(self,plaintext:bytes)->bytes:
33-
"""Encrypt plaintext using RC4"""
34-
self._reset_state()
35-
prga=self._prga()
36-
return bytes([p^next(prga) for p in plaintext])
45+
def encrypt(self, plaintext: bytes) -> bytes:
46+
"""
47+
Encrypt plaintext using RC4
48+
49+
>>> rc4 = RC4(b"SecretKey")
50+
>>> plaintext = b"Hello"
51+
>>> encrypted = rc4.encrypt(plaintext)
52+
>>> len(encrypted) == len(plaintext)
53+
True
54+
"""
55+
self._reset_state()
56+
prga = self._prga()
57+
return bytes([p ^ next(prga) for p in plaintext])
3758

38-
def decrypt(self,ciphertext:bytes)->bytes:
39-
"""Decrypt ciphertext using RC4 (Same as encryption)"""
40-
return self.encrypt(ciphertext)
59+
def decrypt(self, ciphertext: bytes) -> bytes:
60+
"""
61+
Decrypt ciphertext using RC4
62+
63+
>>> rc4 = RC4(b"SecretKey")
64+
>>> ciphertext = rc4.encrypt(b"Hello")
65+
>>> rc4.decrypt(ciphertext) == b"Hello"
66+
True
67+
"""
68+
return self.encrypt(ciphertext)
4169

4270

4371
if __name__ == "__main__":
44-
key=b"SecretKey"
45-
rc4=RC4(key)
72+
import doctest
73+
doctest.testmod()
74+
75+
key = b"SecretKey"
76+
rc4 = RC4(key)
4677

47-
plaintext=b"Hello, RC4 Cipher!"
48-
print("Original:",plaintext)
78+
plaintext = b"Hello, RC4 Cipher!"
79+
print(f"Original: {plaintext}")
4980

50-
ciphertext=rc4.encrypt(plaintext)
51-
print("Encrypted:",ciphertext)
81+
ciphertext = rc4.encrypt(plaintext)
82+
print(f"Encrypted: {ciphertext}")
5283

53-
decrypted_text=rc4.decrypt(ciphertext)
54-
print("Decrypted:",decrypted_text)
55-
56-
assert plaintext==decrypted_text, "Decryption failed"
84+
decrypted_text = rc4.decrypt(ciphertext)
85+
print(f"Decrypted: {decrypted_text}")
86+
87+
assert plaintext == decrypted_text, "Decryption failed!"
5788
print("Encryption and decryption successful.")

0 commit comments

Comments
 (0)