https://kabeor.cn/RC4%E5%8A%A0%E5%AF%86%E7%AE%97%E6%B3%95%E5%8F%8A%E9%80%86%E5%90%91%E6%96%B9%E6%B3%95%E5%88%9D%E6%8E%A2/#%E5%8A%A0%E5%AF%86-%E8%A7%A3%E5%AF%86-%E5%8E%9F%E7%90%86

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)