apppublic/appPublic/rc4.py

151 lines
3.8 KiB
Python
Raw Normal View History

2019-07-16 16:33:07 +08:00
# -*- coding: utf-8 -*-
2022-02-24 13:24:49 +08:00
import time
import datetime
2019-07-16 16:33:07 +08:00
import random, base64
from hashlib import sha1
class RC4:
2019-08-12 11:55:18 +08:00
def __init__(self,data_coding='utf8'):
2019-07-16 16:33:07 +08:00
self.bcoding = 'iso-8859-1'
self.dcoding = data_coding
self.salt = b'AFUqx9WZuI32lnHk'
def _crypt(self,data,key):
"""RC4 algorithm return bytes"""
x = 0
box = [i for i in range(256) ]
for i in range(256):
x = (x + box[i] + key[i % len(key)]) % 256
box[i], box[x] = box[x], box[i]
x = y = 0
out = []
for char in data:
x = (x + 1) % 256
y = (y + box[x]) % 256
box[x], box[y] = box[y], box[x]
out.append(chr(char ^ box[(box[x] + box[y]) % 256]))
return ''.join(out).encode(self.bcoding)
2021-07-13 16:13:59 +08:00
def encode_bytes(self, bdata, key):
a = sha1(key + self.salt)
k = a.digest()
data = self.salt + self._crypt(bdata, k)
return data
2019-08-12 11:55:18 +08:00
def encode(self,data, key,encode=base64.b64encode, salt_length=16):
2019-07-16 16:33:07 +08:00
"""RC4 encryption with random salt and final encoding"""
2021-07-13 16:13:59 +08:00
if type(data)==type(''):
data = data.encode(self.dcoding)
key = key.encode(self.bcoding)
self.encode_bytes(data, key)
2019-07-16 16:33:07 +08:00
if encode:
data = encode(data)
return data.decode(self.dcoding)
2021-07-13 16:13:59 +08:00
def decode_bytes(self, data, key):
salt_length = 16
salt = data[:salt_length]
a = sha1(key + self.salt)
k = a.digest() #.decode('iso-8859-1')
r = self._crypt(data[salt_length:], k)
return r
2019-08-12 11:55:18 +08:00
def decode(self,data, key,decode=base64.b64decode, salt_length=16):
2019-07-16 16:33:07 +08:00
"""RC4 decryption of encoded data"""
2021-07-13 16:13:59 +08:00
if type(data)==type(''):
data = data.encode(self.dcoding)
key = key.encode(self.bcoding)
2019-07-16 16:33:07 +08:00
if decode:
data = decode(data)
2021-07-13 16:13:59 +08:00
r = self.decode_bytes(data, key)
2019-07-16 16:33:07 +08:00
return r.decode(self.dcoding)
2022-02-24 13:24:49 +08:00
class KeyChain(object):
def __init__(self, seed_str, crypter, keylen=23):
self.seed_str = seed_str
self.crypter = crypter
self.keylen = keylen
self.keypool = {
}
2022-02-28 12:06:25 +08:00
delta = datetime.timedelta(0)
self.timezone = datetime.timezone(delta, name='gmt')
2022-02-24 13:24:49 +08:00
def genKey(self, y, m, d):
vv = y * 1000 + m * 100 + d
if self.keypool.get(vv):
return self.keypool[vv]
v = vv
k1 = 0
k = ''
m = len(self.seed_str)
while k1 < self.keylen:
j = v % self.keylen
v = v - (j + k1) * m + self.keylen
k = k + self.seed_str[j]
k1 += 1
key = k.encode('utf-8')
self.keypool[vv] = key
dates = [ d for d in self.keypool.keys() ]
if len(dates) > 6:
d = min(dates)
del self.keypool[d]
return key
def encode(self, text):
bdata = text.encode('utf-8')
return self.encode_bytes(bdata)
def encode_bytes(self, bdata):
2022-02-28 12:06:25 +08:00
dt = datetime.datetime.now(self.timezone)
2022-02-24 13:24:49 +08:00
key = self.genKey(dt.year, dt.month, dt.day)
data = key + bdata
return self.crypter.encode_bytes(data, key)
def _decode(self, data, key):
d = self.crypter.decode_bytes(data, key)
if d[:len(key)] == key:
return d[len(key):]
return None
def decode_bytes(self, data):
2022-02-28 12:06:25 +08:00
dt = datetime.datetime.now(self.timezone)
2022-02-24 13:24:49 +08:00
key = self.genKey(dt.year, dt.month, dt.day)
d = self._decode(data, key)
if d is not None:
return d
if dt.hour == 0 and dt.minute < 1:
ndt = dt + datetime.timedelta(-1)
key = self.genKey(ndt.year, ndt.month, ndt.day)
return self._decode(data, key)
if dt.hour ==23 and dt.minute == 59:
ndt = dt + datetime.timedelta(1)
key = self.genKey(ndt.year, ndt.month, ndt.day)
return self._decode(data, key)
return None
2019-07-16 16:33:07 +08:00
2022-02-24 13:24:49 +08:00
def decode(self, data):
d = self.decode_bytes(data)
if d is None:
return None
return d.decode('utf-8')
2019-07-16 16:33:07 +08:00
if __name__=='__main__':
2019-07-16 17:00:48 +08:00
# 需要加密的数据长度没有限制
2019-07-16 16:33:07 +08:00
# 密钥
2022-02-24 13:24:49 +08:00
2021-07-13 16:13:59 +08:00
data=b"231r3 feregrenerjk gkht324g8924gnfw k;ejkvwkjerv"
key = b'123456'
2019-08-12 11:55:18 +08:00
rc4 = RC4()
2022-02-24 13:24:49 +08:00
kc = KeyChain('in the heaven, we are equal', rc4)
2019-07-16 16:33:07 +08:00
print(data)
# 加码
2022-02-24 13:24:49 +08:00
encoded_data = kc.encode_bytes(data)
2019-07-16 16:33:07 +08:00
print(encoded_data,len(encoded_data) )
# 解码
2022-02-24 13:24:49 +08:00
decoded_data = kc.decode_bytes(encoded_data)
2021-07-13 16:13:59 +08:00
print(data, decoded_data, decoded_data==data)