In [1]:
get_ipython().ast_node_interactivity = 'all'
RC4, also known as ARC4 or ARCFOUR, is a stream cipher.
In [2]:
from collections import namedtuple class RC4: def __init__(self): self.S = list(range(256)) self.i = 0 self.j = 0
In [3]:
RC4()
Out [3]:
<__main__.RC4 at 0x7f06805985b0>
In [4]:
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] = x
In [5]:
r = RC4() r.init_key(b"testkey")
In [6]:
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]
In [7]:
r = RC4() r.init_key(b"testkey", rounds=2**16) [r.get_byte() for _ in range(5)]
Out [7]:
[63, 174, 37, 137, 119]
In [8]:
class RC4(RC4): def get_buf(self, size): buf = bytearray(size) for i in range(size): buf[i] = self.get_byte() return buf
In [9]:
def 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")
Out [9]:
True
Out [9]:
True
Out [9]:
True
In []: