DES算法
好久没写过博客啦,最近在gao搞Qt,做出漂亮的UI确实挺难的,做美工也不简单啊,好啦,言归正传,下面是实现DES的python源码,是借鉴了开源中国一个大师的源码写出来的,直接贴啦。
加密部分:
#!/usr/bin/python #coding:utf-8 from DESstruction import * import re __all__ = ['desencode'] class DES(): def __init__(self): pass #加密 def code(self, former_code, key, code_len, key_len): output = "" trun_len = 0 #将密文和密钥转换为二进制 code_string = self.hexTobin(former_code, code_len) code_key = self.hexTobin(key, key_len) #如果密钥长度不是16的整数倍则以增加0的方式变为16的整数倍 if code_len % 16 != 0: real_len = (code_len / 16) * 16 + 16 else: real_len = code_len if key_len % 16 != 0: key_len = (key_len / 16) * 16 + 16 key_len *= 4 #每个16进制占4位 trun_len = 4 * real_len #对每64位进行一次加密 for i in range(0, trun_len, 64): run_code = code_string[i : i+64] l = i % key_len run_key = code_key[l : l+64] #64位明文、密钥初始置换 run_code = self.code_Firstchange(run_code) run_key = self.key_Firstchange(run_key) #16次迭代 for j in range(16): #取出明文左右32位 code_r = run_code[32 : 64] code_l = run_code[0 : 32] #64左右交换 run_code = code_r #右边32位扩展置换 code_r = self.code_Expand(code_r) #获取本轮子密钥 key_l = run_key[0:28] key_r = run_key[28 : 56] key_l = key_l[d[j] : 28] + key_l[0 : d[j]] key_r = key_r[d[j] : 28] + key_r[0 : d[j]] run_key = key_l + key_r key_y = self.key_Secondchange(run_key) #异或 code_r = self.code_xor(code_r,key_y) #S盒代替/选择 code_r = self.key_Sbox(code_r) #P转换 code_r = self.key_Pbox(code_r) #异或 code_r = self.code_xor(code_l, code_r) run_code += code_r #32互换 code_r = run_code[32 : 64] code_l = run_code[0 : 32] run_code = code_r + code_l #将二进制转换为16进制、逆初始置换 output += self.code_Inversepermutation(run_code) return output #将十六进制转换为二进制字符串 def hexTobin(self, code, lens): new_code = '' lens = lens % 16 for key in code: code_ord = int(key,16) new_code += self.Tobin(code_ord, 4) if lens != 0: new_code += '0' * (16 - lens) * 4 return new_code #二进制转换 def Tobin(self, o, lens): new_code = '' for i in range(lens): new_code = str(o >> i & 1) + new_code return new_code #密文或明文初s始置换 def code_Firstchange(self, code): changed_code = '' for i in range(64): changed_code += code[ip[i] - 1] return changed_code #密钥初始置换 def key_Firstchange (self, key): changed_key = '' for i in range(56): changed_key += key[pc1[i] - 1] return changed_key #扩展置换 def code_Expand(self, code): new_list = '' for i in range(48): new_list += code[e[i] - 1] return new_list #密钥置换选择2 def key_Secondchange(self, key): new_list = '' for i in range(48): new_list += key[pc2[i] - 1] return new_list #异或 def code_xor(self, code, key): code_len = len(key) new_list = '' for i in range(code_len): if code[i] == key[i]: new_list += '0' else: new_list += '1' return new_list #S盒代替选择置换 def key_Sbox(self, key): new_list = '' for i in range(8): row = int(str(key[i * 6]) + str(key[i * 6 + 5]), 2) raw = int(str(key[i * 6 + 1]) + str(key[i * 6 + 2]) + str(key[i * 6 + 3]) + str(key[i * 6 + 4]), 2) new_list += self.Tobin(s[i][row][raw], 4) return new_list #置换P def key_Pbox(self, code): new_list = '' for i in range(32): new_list += code[p[i] - 1] return new_list #逆初始置换 def code_Inversepermutation(self, code): lens = len(code) / 4 new_list = '' for i in range(lens): list = '' for j in range(4): list += code[ip_1[i * 4 + j] - 1] new_list += "%x" % int(list, 2) return new_list def DES_encode(former_code,key): #转换为16进制 former_code = Tohex(former_code) key = Tohex(key) des = DES() key_len = len(key) code_len = len(former_code) if code_len < 1 or key_len < 1: print 'error input' return False key_code = des.code(former_code, key, code_len, key_len) return key_code #将unicode字符转换为16进制 def Tohex(string): new_string = '' for i in string: new_string += "%02x" % ord(i) return new_string def tounicode(string): return_string = '' string_len = len(string) for i in range(0, string_len, 2): return_string += chr(int(string[i : i + 2], 16)) return return_string if __name__ == '__main__': print DES_encode('12083612isawonder', '0f1571c947刘')
解密方法:
#!/usr/bin/python #coding:utf-8 from DESstruction import * import re __all__ = ['desdecode'] class DES(): def __init__(self): pass #解密 def decode(self, string, key, key_len, string_len): output = "" trun_len = 0 num = 0 #将密文转换为二进制 code_string = self.hexTobin(string, string_len) #获取字密钥 code_key = self.getKey(key, key_len) #如果密钥长度不是16的整数倍则以增加0的方式变为16的整数倍 real_len = (key_len / 16) + 1 if key_len % 16 != 0 else key_len / 16 trun_len = string_len * 4 #对每64位进行一次加密 for i in range(0, trun_len, 64): run_code = code_string[i : i + 64] run_key = code_key[num % real_len] #64位明文初始置换 run_code = self.code_Firstchange(run_code) #16次迭代 for j in range(16): code_r = run_code[32 : 64] code_l = run_code[0 : 32] #64左右交换 run_code = code_r #右边32位扩展置换 code_r = self.code_Expand(code_r) #获取本轮子密钥 key_y = run_key[15 - j] #异或 code_r = self.code_xor(code_r, key_y) #S盒代替/选择 code_r = self.code_Sbox(code_r) #P转换 code_r = self.code_Pbox(code_r) #异或 code_r = self.code_xor(code_l,code_r) run_code += code_r num += 1 #32互换 code_r = run_code[32 : 64] code_l = run_code[0 : 32] run_code = code_r + code_l #将二进制转换为16进制、逆初始置换 output += self.code_Inversepermutation(run_code) return output #将十六进制转换为二进制字符串 def hexTobin(self, code, lens): return_code = '' lens = lens % 16 for key in code: code_ord = int(key,16) return_code += self.Tobin(code_ord, 4) if lens != 0: return_code += '0' * (16 - lens) * 4 return return_code #获取子密钥 def getKey(self, key, key_len): #将密钥转换为二进制 code_key = self.hexTobin(key, key_len) a = [''] * 16 real_len = (key_len / 16) * 16 + 16 if key_len % 16 != 0 else key_len b = [''] * (real_len / 16) for i in range(real_len / 16): b[i] = a[ : ] num = 0 trun_len = 4 * key_len for i in range(0, trun_len, 64): run_key = code_key[i : i + 64] run_key = self.key_Firstchange(run_key) for j in range(16): key_l = run_key[0 : 28] key_r = run_key[28 : 56] key_l = key_l[d[j] : 28] + key_l[0 : d[j]] key_r = key_r[d[j] : 28] + key_r[0 : d[j]] run_key = key_l + key_r key_y = self.key_Secondchange(run_key) b[num][j] = key_y[ : ] num += 1 return b #密文或明文初始置换 def code_Firstchange(self, code): changed_code = '' for i in range(64): changed_code += code[ip[i] - 1] return changed_code #扩展置换 def code_Expand(self, code): return_list = '' for i in range(48): return_list += code[e[i] - 1] return return_list #异或 def code_xor(self, code, key): code_len = len(key) return_list = '' for i in range(code_len): if code[i] == key[i]: return_list += '0' else: return_list += '1' return return_list #二进制转换 def Tobin(self, o, lens): return_code = '' for i in range(lens): return_code = str(o >> i & 1) + return_code return return_code #S盒代替选择置换 def code_Sbox(self, key): return_list='' for i in range(8): row = int(str(key[i * 6]) + str(key[i * 6 + 5]), 2) raw = int(str(key[i*6+1]) + str(key[i * 6 + 2]) + str(key[i * 6 + 3]) + str(key[i * 6 + 4]), 2) return_list += self.Tobin(s[i][row][raw], 4) return return_list #置换P def code_Pbox(self, code): return_list = '' for i in range(32): return_list += code[p[i] - 1] return return_list #密钥初始置换 def key_Firstchange(self, key): changed_key = '' for i in range(56): changed_key += key[pc1[i] - 1] return changed_key #逆初始置换 def code_Inversepermutation(self, code): return_list = '' for i in range(16): list = '' for j in range(4): list += code[ip_1[i * 4 + j] - 1] return_list += "%x" % int(list, 2) return return_list #密钥置换选择2 def key_Secondchange(self, key): return_list = '' for i in range(48): return_list += key[pc2[i] - 1] return return_list #入口函数 def DES_decode(from_code, key): key = tohex(key) des = DES() key_len = len(key) string_len = len(from_code) if string_len % 16 != 0: return False if string_len < 1 or key_len < 1: return False key_code = des.decode(from_code, key, key_len, string_len) return tounicode(key_code) #将unicode字符转换为16进制 def tohex(string): return_string = '' for i in string: return_string += "%02x" % ord(i) return return_string def tounicode(string): return_string = '' string_len = len(string) for i in range(0, string_len, 2): return_string += chr(int(string[i : i + 2], 16)) return return_string #测试 if __name__ == '__main__': print DES_decode('3530b23e0d9d0f5c2cb2602ac98fd26382ed6769d3dcf00a', '0f1571c947刘')