# RC4 Python implementation

I'm cooking 2021-11-25 09:45:59
rc4 rc python implementation

RC4 The algorithm is a stream cipher （ Byte oriented operations ）, Key length is variable （ Generate the key stream according to the plaintext length ）
RC4 Encryption process ：
1, Initialize the status array S： length 256 byte , Every S[i] by 1 Bytes ,S[i] The value of is 0-255
2, Initialize temporary array T：T The length of is 256 byte , Every T[i] by 1 Bytes ,
First, generate a key array Key, Key The length of is 1~256 byte ( Random ), Every Key[i] by 1 Bytes , And each Key[i] The value of is randomly generated ;
And then the array Key Each of the Key[i] Take turns and loop into the array T, such as Key[]=1,2,3,4,5 , Then put it into the array T：T[] =1,2,3,4,5,1,2,3,4,5…1,2,3,4,5,1,2 Will array T fill , This array T Finished initializing , And random ;
3, Initial permutation array S ： After initialization T, And a variable j=0, Scramble the array S, send S It's random ：
Through for each S[i], adopt j = (j + S[i] + T[I]) mod 256 , In exchange for S[i] and S[j] Value ;
My understanding of this step ： Because the initialized array T It's random , So it will T Element is added to get S[j] And replace S[i] and S[j] , Make the array S Pseudorandom ;
4, Generate key stream KeyStream： First, get the plaintext length , Decide to generate a key stream of the same length as plaintext ,
Through to each S[i],j=0,j=(j+S[i]) mod 256 take S[i] And S[j] substitution , When i>255, go back to S[0], Repeat the replacement operation again :
j,t = 0,0
for i in range(txtlen): // txtlen Is the length of the plaintext , Through the loop , Generate equal length key stream
i = i mod 256 // adopt mod 256 , Ensure that subsequent pairs of arrays S Repetitive operation
j = (j+S[i]) mod 256
tmp = S[i]
S[i] = S[j] // substitution S[i] And S[j]
S[j] = tmp
t = (S[i] + S[j]) mod 256
KeyStream.append(S[t]) //S[t] by A bit in the key stream
My understanding of this step ： Suppose a box is called S, There is a row of 256 One says from 0-255 A number ball , And this 256 The ball was disrupted earlier , Now you need to start from S The first one in the box （i）, And through the formula j = (j+S[i]) mod 256 What you get is j individual , Write down the number on the ball and pass the formula t = (S[i] + S[j]) mod 256 Get number t, Then you go and find out the second t A little ball , The number on it S[t] Is a bit in the key stream , And you put the first （i） The ball and the second j Exchange a small ball and put it back S box , Then repeat the steps just now to touch the second （i） And the j And so on , Until you repeat this step txtlen Time ; notes ： When you touch the first 256 individual （ The last one ）, But you haven't finished yet txtlen Time , So the next time you touch the ball is to go back to the first start , This is the corresponding pair array S Repetitive operation ;

Attach reference code , If there is any wrong , I would appreciate your comments. ^-^：

``````#encoding = utf-8
import random
# Initialization vector S
def init_S():
global S
for i in range(256):
S.append(i)
# Initialization vector T
def init_T():
global Key,T
keylen = random.randint(1,256)
for i in range(keylen):
index = random.randint(0,61) # Get a random temporary key Key
Key.append(WordList[index])
for i in range(256):
tmp = Key[i % keylen] # Initialization vector T
T.append(tmp)
# The initial displacement S[i]
def swap_S():
global S,T
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
# Key stream generation
def Get_KeyStream():
global S,text,KeyStream
txtlen = len(text)
j,t = 0,0
for i in range(txtlen):
i = i % 256
j = (j+S[i]) % 256
tmp = S[i]
S[i] = S[j]
S[j] = tmp
t = (S[i] + S[j]) % 256
KeyStream.append(S[t])
# encryption & Decrypt
def Get_code():
global PlainText,CryptoText,KeyStream,text
for i in range(len(text)):
CryptoText += chr(ord(text[i]) ^ KeyStream[i]) # encryption
for i in range(len(text)):
PlainText += chr(ord(CryptoText[i]) ^ KeyStream[i]) # Decrypt
print('''[+]================= Began to encrypt ==================''')
print('''[+]================= Start decrypting ==================''')
if __name__ == '__main__' :
T,S,Key = [],[],[]
PlainText,CryptoText,KeyStream = '','',[]
WordList = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" # Used to generate temporary keys Key
print(''' ——————— ———————— —————— | —— \ / _____| / | | | |__) | | / / —— | | | __ / | | / |_| | | ^__^ is easy ~, that right ? | | \ \ | |_____ |______| | |__| \__\ \________| |_| ██████╗ ██████╗██╗ ██╗ ███╗ ███╗ ██╗███████╗ ███████╗ █████╗ ███████╗██╗ ██╗ ██╔══██╗██╔════╝██║ ██║ ██╔██╗ ██╔██╗ ██║██╔════╝ ██╔════╝██╔══██╗██╔════╝╚██╗ ██╔╝ ██████╔╝██║ ███████║ ╚═╝╚═╝ ╚═╝╚═╝ ██║███████╗ █████╗ ███████║███████╗ ╚████╔╝ ██╔══██╗██║ ╚════██║ ██║╚════██║ ██╔══╝ ██╔══██║╚════██║ ╚██╔╝ ██║ ██║╚██████╗ ██║ ███████╗ ██║███████║ ███████╗██║ ██║███████║ ██║ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚══════╝ ╚═╝╚══════╝ ╚══════╝╚═╝ ╚═╝╚══════╝ ╚═╝ ''')
text = input("[+]please input you Plaintext here : ")
init_S()
init_T()
swap_S()
Get_KeyStream()
Get_code()
``````

Screenshot of the code running correctly ：

https://pythonmana.com/2021/11/20211109005248956u.html