|
# For python 3.0.
# From Li Bo
Import struct, sys, OS, binascii
"""
RC4 Encryption Algorithm
16*16 S box
Encryption unit: short
"""
Def RC4 (pkey, keylen, pin, dlen ):
N = 65536
S = list (range (N ))
J = 0
For I in range (N ):
J = (j + S [I] + pkey [I % keylen]) % N
Temp = S [I]
S [I] = S [j]
S [j] = temp
I = j = 0
Pout = B''
For x in range (dlen ):
I = I + 1
J = (j + S [I]) % N
Temp = S [I]
S [I] = S [j]
S [j] = temp
Pout + = struct. pack ('h', pin [x] ^ S [(S [I] + S [j]) % N])
Return (pout)
# Bytes-> short
Def Coding (data ):
If (len (data) % 2 ):
Data + = B '\ 0'
Dlen = len (data) // 2
Return (struct. unpack (str (dlen) + 'h', data ))
# Short-> bytes
Def unCoding (data ):
D = B''
For I in range (len (data )):
D + = struct. pack ('h', data [I])
Return (d)
# Generate a 32-byte key
Def CreatKey (Keyt ):
Pl = len (Keyt)
Key = B''
R = 0
For I in range (32 ):
K = (Keyt [r % pl] + I) % 256
Key + = struct. pack ('B', k)
R + = 1
Return Key
# Update a key
Def UpdataKey (Keyt ):
Key = unCoding (Keyt)
# Shift left of Loop
Key = Key [1:] + struct. pack ('B', Key [0])
Tem = 0
# Sum
For I in range (len (Key )):
Tem + = Key [I];
Keyo = B''
# Xor
For I in range (len (Key )):
Keyo + = struct. pack ('B', (Key [I] ^ tem) % 256)
Tem + = Keyo [I]> 3
Tem = tem %256
Return (Coding (Keyo ))
If _ name _ = '_ main __':
# Retrieving input files
If len (sys. argv) = 1:
Filename = input ('source file :')
Else:
Filename = sys. argv [1]
Try:
Fin = open (filename, 'rb ')
Except t:
Print ('failed to open the file! ')
Input ()
Sys. exit ()
Print (filename)
# Open an output file
If filename [-4:] = '. RC4 ':
EID = 1
Key = input ('input decryption key: '). encode ()
Ofilename = filename [:-4]
Else:
EID = 2
Key = input ('input encryption key: '). encode ()
Ofilename = filename + '. RC4'
Key = Coding (CreatKey (key ))
Key = UpdataKey (key)
# Process duplicate names
While OS. path. exists (ofilename ):
Ofilename = OS. path. dirname (ofilename) + '\ replicase' + OS. path. basename (ofilename)
Fout = open (ofilename, 'wb ')
Print (ofilename)
# Decryption
If eID = 1:
# Read File Length
Filelen = struct. unpack ('I', fin. read (4) [0]
Print ('flielen = ', filelen,' \ n ......')
While 1:
# Read block size
Ps = fin. read (2)
If not ps:
# End of File
Break
Packsize = struct. unpack ('h', ps) [0]
# Read data
Dd = fin. read (packsize)
# Decryption
Dd = Coding (dd)
X = RC4 (key, len (key), dd, len (dd ))
Key = UpdataKey (key)
# Crc
Crc = struct. unpack ('I', fin. read (4) [0]
If binascii. crc32 (x )! = Crc:
Print ('crc32 verification error! ', Crc, binascii. crc32 (x ))
Input ()
Sys. exit ()
Fout. write (x)
# Fill position at the end of Cropping
Fout. truncate (filelen)
# Encryption
Elif eID = 2:
# Obtain the file length
Fin. seek (0, 2)
Filelen = fin. tell ()
Print ('flielen = ', filelen,' \ n ......')
Fin. seek (0, 0)
Fout. write (struct. pack ('I', filelen ))
While 1:
# Read data
Dd = fin. read (1, 65534)
If not dd:
# End of File
Break
# End Filling
Srl = len (dd)
If srl % 2:
Srl + = 1;
Dd + = B '\ 0'
# Crc
Crc = struct. pack ('I', binascii. crc32 (dd ))
# Encrypt data
Dd = Coding (dd)
X = RC4 (key, len (key), dd, len (dd ))
Key = UpdataKey (key)
# Writing files
Fout. write (struct. pack ('h', srl ))
Fout. write (x)
Fout. write (crc)
Fin. close ()
Fout. close ()
Print ('OK! ')
Input ()
|