RC4算法加解密

        今天学习了RC4算法,加密逻辑比较简单,主要是分成三部分

  •         密钥调度算法(KSA)
  •         生成密钥流K表(PRGA)
  •         最后将密钥调度算法得到的s表和密钥流产生的k表进行异或,得到密钥

下面上代码,解密的逻辑把加密反过来就好

'''
RC4算法加解密

'''

#1.密钥调度算法ksa,通过种子密钥打乱s表
def KSA(seed):
    #创建s表
    s = list(range(256))
    print(f's为{s}')
    #创建t表
    t = list(range(256))
    for i in range(256):
        t[i] = seed[i%len(seed)]
    print(f't为{t}')
    #用t表置换s表
    j = 0
    for i in range(256):
        j = (j + s[i] + ord(t[i])) % 256
        tmp = s[i]
        s[i] = s[j]
        s[j] = tmp
    return s
    #新的s表替换完毕
#2.通过明文的长度,生成密钥流PRGA
def PRGA(plaintext,length):
    i = 0
    j = 0
    k = list(range(length))
    for x in k:
        i = (i + 1) % 256
        j = (j + s[i]) % 256
        #置换s[i]和s[j]
        s[i],s[j] = s[j],s[i]
        t = (s[i] + s[j]) % 256
        k[x] = s[t]
        print(f'{x,k[x]}')
    return k

if __name__ == '__main__':
    enter = int(input('加密输入0\n解密输入1\n'))
    # enter = 1
    if enter == 0:
        seed = input('请输入种子密钥: ')
        # seed = 'love'
        s = KSA(seed)
        plaintext = input('请输入明文: ').lower()
        # plaintext = 'wozuishuai'
        length = len(plaintext)
        #得到的是十进制的数据
        k = PRGA(plaintext,length)
        print(f'k为{k}')
        #明文的十六进制和k的十六进制异或可得密文
        p_list = []
        for i in plaintext:
            p_list.append(ord(i))
        print(f'p_list为{p_list}')
        ciphertext = []
        for p,kk in zip(p_list,k):
            c = hex(int(p)^int(kk)).replace('0x','')
            if len(c) < 2:
                c = '0' + c
                ciphertext.append(c)
            else:
                ciphertext.append(c)
        print(f'种子密钥为: {seed}' + '密文为: ' + ''.join(ciphertext))

    if enter == 1:
        seed = input('请输入种子密钥: ')
        # seed = 'secret'
        s = KSA(seed)
        # ciphertext = '9c5fbc7bfbd1afdf56b8'
        ciphertext = input('请输入密文: ').lower()
        length = int(len(ciphertext)/2)
        k = PRGA(ciphertext,length)
        print(f'k为{k}')
        c = []
        for i,j in zip(ciphertext,range(int(len(ciphertext)/2))):
            c.append(ciphertext[0 + 2 * j:2 + 2 * j])
        print(f'c为{c}')
        result = []
        for i,j in zip(k,c):
            r = chr(int(i ^ int(j,16)))
            result.append(r)
        print(f'种子密钥为: {seed}' + '明文为: ' + ''.join(result))

有一个问题需要注意的是,比如给wozuishuai(10位)加密的密钥应该是970cdb33d77a03b18a28(20位)而不是97cdb33d77a3b18a28(18位),如果k的字符不是成对存在的,比如c需要补成0c,否则会影响解密结果(在代码加密中已经自动补0了,解密的话直接用产生的密钥即可)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值