0%

RC4加解密算法python简单实现

序列密码又称流密码,原理是明文流和密钥流按顺序逐位异或运算,从而产出密文流,序列密码属于对合运算。

以下是典型的序列密码RC4的加解密算法实现。其中秘钥流产生算法由RSA和PRGA两个核心子算法组成。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# coding:utf-8
# RC4 python实现代码
# 仅支持128位ASCII码字符文本加解密,要支持任意输入需要更换编码方式
# 秋风木叶 2019-3-27

from FrankTools import ItoB, XOR, StoB, BtoS, swap

def KeyGenerator(K, n):

# RSA(The Key-Scheduling Algorithm)
# 秘钥调度算法
S = [i for i in range(0, 256)]
R = []
for i in range(0,256):
R.append(ord(K[i % len(K)]))
j = 0
for i in range(0,256):
j = (j + S[i] + R[i]) % 256
S[i], S[j] = swap(S[i], S[j])
#print('随机化后的S {}'.format(S))

# PRGA(The Pseudo-Random Generating Algorithm)
# 伪随机子密码生成算法
i = 0
j = 0
K_list = []
while(n):
i = (i+1)%256
j = (j+S[i])%256
S[i],S[j] = swap(S[i],S[j])
t = (S[i]+S[j])%256
K_list.append(S[i])
# K_list存储生成的秘钥
n -= 1

# 秘钥转换为二进制序列
k=''
for i in K_list:
k += ItoB(i)
#print('秘钥序列为:{}'.format(BtoS(k)))
return k

def Encrypt(M, K):
M_list = StoB(M)
K_list = KeyGenerator(K, len(M))
#print('------------{0},{1}'.format(len(M_list),len(K_list)))
#print(M_list,K_list)
return XOR(M_list,K_list)

def Decrypt(C, K):
C_list = C
K_list = KeyGenerator(K, len(C)/8)
#print('----------------{0},{1}'.format(len(C_list),len(K_list)))
#print(C_list,K_list)
return BtoS(XOR(C_list, K_list))

if __name__=='__main__':
#print('\n>>>Test!')
M = 'MING CHEN WU DIAN FA DONG FAN GONG'
K = 'XING CHUI PING YE KUO YUE YONG DA JIANG LIU'
C = Encrypt(M, K)
M1 = Decrypt(C, K)
print('明文加密之后产生的密文是: {}'.format(C))
print('解密出的明文是: {}'.format(M1))

其中引用了FrankTools模块中的ItoB, XOR, StoB, BtoS, swap函数,FrankTools模块中将常用函数打包以便调用,展示如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
# coding:utf-8
# Frank的工具箱
# 凌云工具箱
# 起因:前几天用python实现了几种古典密码算法,期间频繁涉及到字符串、二进制、数字串之间的转换,
# 前几次都是在多个文件中分别去写,一点也不美,现在将其打包在一起,我也可以增加一些其他功能,构成
# 我的专属工具箱O(∩_∩)O哈哈~

# 更新日期 2019.3.29
# 更新内容:新增swap()函数

'''
ItoB(int n):
功能:数字转二进制
输入:0-255之间的整数
返回:8位二进制字符串,不足8位用0补齐

CtoB(char ch):
功能:单字符转二进制
输入:单字符;
返回:8位二进制字符串,不足8位用0补齐。

BtoS(string s):
功能:将二进制字符串转为字符串;
注意:每8位二进制对应一个字符,无奇偶校验;
返回:转换后的字符串。

OXR(string L, string R):
功能: 将另个二进制字符串逐位进行异或运算;
输入:两个等长二进制字符串;
输出:异或运算后的等长二进制字符串。

swap(a, b):
用于交换a, b两个变量的值
'''

# 数字转二进制,不足八位补0
# (二进制结果以字符串的形式提供)
def ItoB(I):
'''
功能:数字转二进制
输入:0-255之间的整数
返回:8位二进制字符串,不足8位用0补齐
'''
if(isinstance(I,int) == False or I < 0 or I > 255):
return '参数错误!'

BinarySequence = ''
while(True):
if(I % 2 == 0):
BinarySequence += '0'
else:
BinarySequence += '1'
I = I // 2
if(I == 1):
break
#print(OrdCh,BinarySequence)
BinarySequence += '1'
# 补齐8位
length = 8 - len(BinarySequence)
while(length):
BinarySequence += '0'
length -= 1
#print('BinarySequence:{}'.format(BinarySequence))
return BinarySequence[::-1]


# 字符串(或单字符)转二进制,单字符不足n位补0
# (二进制结果以字符串的形式提供)
def StoB( S, n=8):
'''
功能:字符串转二进制
输入:字符串s, 每个字母位数n(默认值为8,实际输入至少7)
返回:二进制字符串,单字符不足n位用0补齐
'''
if(isinstance(n,int) == False or n < 7):
return '参数错误!'

Bin = ''

for c in [ord(i) for i in S]:
#print('c',c)
bin_unit = ''
while(True):
if(c % 2 == 0):
bin_unit += '0'
else:
bin_unit += '1'
c = c // 2
if(c == 1):
break
bin_unit += '1'

# 补齐n位
length = n - len(bin_unit)
#print(length)
while(length):
bin_unit += '0'
length -= 1
#print(length,bin_unit)
#print(bin_unit)
Bin += bin_unit[::-1]
return Bin

# 二进制转字符串(或单字符)
def BtoS(Bin,n=8):
'''
功能:将二进制字符串转为字符串
注意:每n位二进制对应一个字符,无奇偶校验
返回:转换后的字符串
'''
St = ''
OrdCh = 0
length = n
for i in Bin:
length -= 1
OrdCh += (ord(i)-ord('0'))*(2**length)
#print(length,i,OrdCh)
if(length == 0):
St += chr(OrdCh)
length = n
OrdCh = 0
return St

# 二进制异或运算
# exclusive OR,缩写成xor
def XOR(L, R):
'''
功能: 将两个二进制字符串逐位进行异或运算
输入:两个等长二进制字符串
输出:异或运算后的等长二进制字符串
'''
result = ''
for i,j in zip(L, R):
#print(i,j)
if(i == j):
result += '0'
else:
result += '1'
#print('result:{}'.format(result))
return result

# swap
def swap(a,b):
'''
输入:a,b;
输出:b,a.
'''
return b,a

水平和精力所限,疏漏之处难免,欢迎各位多多不吝赐教!
f@tacgib.club


本文作者原创,转载请注明出处!

秋风木叶
2019.03.29
有您的赞赏,我会更加有动力!