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刘')

 

posted @ 2014-05-07 19:41  Q_Gina  阅读(388)  评论(0编辑  收藏  举报