init 是公共部分,先把 0 到 255 不重复的元素放在 S 中,再根据密钥拓展的 k 打乱所有的 S
然后是加解密部分,根据一定的算法(和当前位置和 S 盒当前情况有关)找到两个位置交换 S 盒中元素,然后同时用这两个元素找到 S 盒中的另一个元素和 data 异或。异或的东西只和 key 有关,和 data 无关,所以其自身就是反函数
def KSA(key):
""" Key-Scheduling Algorithm (KSA) """
S = list(range(256))
j = 0
for i in range(256):
j = (j + S[i] + key[i % len(key)]) % 256
S[i], S[j] = S[j], S[i]
return S
def PRGA(S):
""" Pseudo-Random Generation Algorithm (PRGA) """
i, j = 0, 0
while True:
i = (i + 1) % 256
j = (j + S[i]) % 256
S[i], S[j] = S[j], S[i]
K = S[(S[i] + S[j]) % 256]
yield K
def RC4(key, text):
""" RC4 encryption/decryption """
S = KSA(key)
keystream = PRGA(S)
res = []
for char in text:
res.append(char ^ next(keystream))
return bytes(res)