Just to learn the RC4 algorithm, the author of the online Discovery https://ju.outofmemory.cn/entry/46753 show the RC4 python implementation, but the code lacks comments, more obscure, so this article on some of the code is commented, Hope to be able to learn RC4 algorithm Pythoner Helpful.
1 # / usr / bin / python
2 # coding = utf-8
3 import sys, os, hashlib, time, base64
4 def rc4 (string, op = ‘encode’, public_key = ‘ddd’, expirytime = 0):
5 ckey_lenth = 4 #define the length of the IV
6 public_key = public_key and public_key or ‘‘
7 key = hashlib.md5 (public_key) .hexdigest () # md5 the password public_key and return a 32-byte key
8 keya = hashlib.md5 (key [0:16]). Hexdigest () #Made the first 16 bytes of Key md5 and return 32 bytes of keya
9 keyb = hashlib.md5 (key [16:32]). Hexdigest () #Made the last 16 bytes of the key to md5 and return a 32-byte keyb
10
11 #When encrypting, keyc takes the first 4 bytes of md5 of time.time (), which is used as the IV
12 #When decrypting, take the IV from the first 4 bytes of the ciphertext
13 keyc = ckey_lenth and (op == ‘decode’ and string [0: ckey_lenth] or hashlib.md5 (str (time.time ())). Hexdigest () [32-ckey_lenth: 32]) or ‘‘
14
15 #The real key cryptkey is a 64-byte string obtained by keya splicing keya and keyc's md5
16 cryptkey = keya + hashlib.md5 (keya + keyc) .hexdigest ()
17 key_lenth = len (cryptkey) # 64
18
19 #When encrypting, the plaintext to be encrypted is formed by concatenating the 10 bytes of 0 and the plaintext string to be encrypted with the first 16 bytes of the md5 value of keyb and the plaintext string.
20 #When decrypting, the ciphertext is the content of the first 4 bytes of the incoming string and decoded
21 string = op == ‘decode’ and base64.b64decode (string [4:]) or ‘0000000000’ + hashlib.md5 (string + keyb) .hexdigest () [0:16] + string
22 string_lenth = len (string)
twenty three
24 result = ‘‘
25 box = list (range (256))
26 randkey = []
27
28 for i in xrange (255):
29 # Randomly fill the ascii code value of the characters in cryptokey, there will be 4 rounds of repetition, randkey [0] ~ randkey [63], randkey [64] ~ randkey [127], ...
30 randkey.append (ord (cryptkey [i% key_lenth]))
31
32 # Randomly shuffle the list of boxes
33 # cryptkey's real purpose is to generate pseudo-random boxes
34 for i in xrange (255):
35 j = 0
36 j = (j + box [i] + randkey [i])% 256
37 tmp = box [i]
38 box [i] = box [j]
39 box [j] = tmp
40
41 for i in xrange (string_lenth):
42 a = j = 0
43 a = (a + 1)% 256
44 j = (j + box [a])% 256
45 tmp = box [a]
46 box [a] = box [j]
47 box [j] = tmp
48 # The above was disrupted again
49
50 #True plaintext string XOR with random value in box to generate encrypted result
51 #No matter how random it is, because cryptkey and string_length are always the same, so the box will eventually be the same.
52 result + = chr (ord (string [i]) ^ (box [(box [a] + box [j])% 256]))
53 #When decrypting, the ciphertext is XORed with the box to return the plaintext
54
55 if op == ‘decode’:
56 #result [10:26] == hashlib.md5 (result [26:] + keyb) .hexdigest () [0:16], used to verify the integrity of the string
57 if (result [0:10] == '0000000000' or int (result [0:10])-int (time.time ())> 0) and result [10:26] == hashlib.md5 (result [26:] + keyb) .hexdigest () [0:16]:
58 return result [26:] #The first ten bytes are 0, the other 16 bytes are the first 16 bytes of md5 of the plaintext string and keyb, and the last is string
59 else:
60 return None
61 else:
62 #Encryption, return base64 encoding of IV + result
63 return keyc + base64.b64encode (result)
64
65 if __name__ == ‘__main__’:
66 #print rc4 (‘we’, 'encode ’,' 98765’)
67 print rc4 (‘fd09GMhYylNXC5t550VwC5oX9WS4zrB0bI9rs6kvTAMoiGI =‘, ’decode’, ’98765’)
Python implementation of the RC4 algorithm detailed note