DES算法

很久沒寫過博客啦,最近在gao搞Qt,作出漂亮的UI確實挺難的,作美工也不簡單啊,好啦,言歸正傳,下面是實現DES的python源碼,是借鑑了開源中國一個大師的源碼寫出來的,直接貼啦。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劉')
相關文章
相關標籤/搜索