get_ipython().ast_node_interactivity = 'all'RC4, also known as ARC4 or ARCFOUR, is a stream cipher.
from collections import namedtuple
class RC4:
def __init__(self):
self.S = list(range(256))
self.i = 0
self.j = 0RC4()<__main__.RC4 at 0x7f06805985b0>
class RC4(RC4):
def init_key(self, key, rounds=256):
for i in range(256):
self.S[i] = i
j = 0
for i in range(rounds):
i &= 0xFF
j = (j + self.S[i] + key[i % len(key)]) & 0xFF
x = self.S[i]
self.S[i] = self.S[j]
self.S[j] = xr = RC4()
r.init_key(b"testkey")class RC4(RC4):
def get_byte(self):
self.i = (self.i + 1) & 0xFF
self.j = (self.j + self.S[self.i]) & 0xFF
x = self.S[self.i]
self.S[self.i] = self.S[self.j]
self.S[self.j] = x
return self.S[(self.S[self.i] + self.S[self.j]) & 0xFF]r = RC4()
r.init_key(b"testkey", rounds=2**16)
[r.get_byte() for _ in range(5)][63, 174, 37, 137, 119]
class RC4(RC4):
def get_buf(self, size):
buf = bytearray(size)
for i in range(size):
buf[i] = self.get_byte()
return bufdef check_output(key, expected):
r = RC4()
r.init_key(key.encode('ascii'))
size = int(len(expected) / 2)
return r.get_buf(size).hex().upper() == expected.upper()
check_output("Key", "EB9F7781B734CA72A719")
check_output("Wiki", "6044DB6D41B7")
check_output("Secret", "04D46B053CA87B59")True
True
True