DES加密算法的加密过程代码实现(Feistel结构)

帮人写的代码,应该是经典结构。


输入明文 X X X和密钥 K K K后,输出加密后的结果,以及每轮的 L 、 R 、 K L、R、K LRK


代码标注了每个函数的用作,可放心食用。


code:

import copy


class DES:
    # 定义初始置换IP
    IP = [
        58, 50, 42, 34, 26, 18, 10, 2,
        60, 52, 44, 36, 28, 20, 12, 4,
        62, 54, 46, 38, 30, 22, 14, 6,
        64, 56, 48, 40, 32, 24, 16, 8,
        57, 49, 41, 33, 25, 17, 9, 1,
        59, 51, 43, 35, 27, 19, 11, 3,
        61, 53, 45, 37, 29, 21, 13, 5,
        63, 55, 47, 39, 31, 23, 15, 7
    ]

    # 定义逆置换IP-1
    IP_1 = [
        40, 8, 48, 16, 56, 24, 64, 32,
        39, 7, 47, 15, 55, 23, 63, 31,
        38, 6, 46, 14, 54, 22, 62, 30,
        37, 5, 45, 13, 53, 21, 61, 29,
        36, 4, 44, 12, 52, 20, 60, 28,
        35, 3, 43, 11, 51, 19, 59, 27,
        34, 2, 42, 10, 50, 18, 58, 26,
        33, 1, 41, 9, 49, 17, 57, 25
    ]

    # S-Box
    S_BOXES = [
        # S1
        [[14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7],
         [0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8],
         [4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0],
         [15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13]],

        # S2
        [[15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10],
         [3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5],
         [0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15],
         [13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9]],

        # S3
        [[10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8],
         [13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1],
         [13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7],
         [1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12]],

        # S4
        [[7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15],
         [12, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9],
         [10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4],
         [3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14]],

        # S5
        [[2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9],
         [14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6],
         [4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14],
         [11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3]],

        # S6
        [[12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11],
         [10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8],
         [9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6],
         [4, 11, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13]],

        # S7
        [[4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1],
         [13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6],
         [1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2],
         [6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12]],

        # S8
        [[13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7],
         [1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2],
         [7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8],
         [2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11]]
    ]

    # P-置换
    P = [
        16, 7, 20, 21,
        29, 12, 28, 17,
        1, 15, 23, 26,
        5, 18, 31, 10,
        2, 8, 24, 14,
        32, 27, 3, 9,
        19, 13, 30, 6,
        22, 11, 4, 25
    ]

    PC1 = [
        57, 49, 41, 33, 25, 17, 9,
        1, 58, 50, 42, 34, 26, 18,
        10, 2, 59, 51, 43, 35, 27,
        19, 11, 3, 60, 52, 44, 36,
        63, 55, 47, 39, 31, 23, 15,
        7, 62, 54, 46, 38, 30, 22,
        14, 6, 61, 53, 45, 37, 29,
        21, 13, 5, 28, 20, 12, 4
    ]

    PC2 = [
        14, 17, 11, 24, 1, 5,
        3, 28, 15, 6, 21, 10,
        23, 19, 12, 4, 26, 8,
        16, 7, 27, 20, 13, 2,
        41, 52, 31, 37, 47, 55,
        30, 40, 51, 45, 33, 48,
        44, 49, 39, 56, 34, 53,
        46, 42, 50, 36, 29, 32
    ]

    E = [
        32, 1, 2, 3, 4, 5,
        4, 5, 6, 7, 8, 9,
        8, 9, 10, 11, 12, 13,
        12, 13, 14, 15, 16, 17,
        16, 17, 18, 19, 20, 21,
        20, 21, 22, 23, 24, 25,
        24, 25, 26, 27, 28, 29,
        28, 29, 30, 31, 32, 1
    ]

    def __init__(self, X, K):
        """
        :param X: 2进制明文 list
        :param K: 2进制密钥 list
        """
        self.X = X
        self.K = K

        self.k_list = []
        self.c_list = []
        self.d_list = []

        self.l_list = []
        self.r_list = []

        self.init_K()
        self.init_P()
        # 结果
        self.C = self.substitution(self.r_list[-1] + self.l_list[-1], self.IP_1)

    def substitution(self, s, p):
        """
        置换
        :param s: 需要置换的序列,list
        :param p: 置换规则,list
        :return: s 根据 p 置换后的结果,list
        """
        if len(s) < max(p) - 1:
            raise IndexError('max(p) > len(s)')
        res = [s[i - 1] for i in p]
        return res

    def init_K(self):
        """
        得到每一轮的 K
        :return: None
        """
        k0 = self.substitution(self.K, self.PC1)
        self.c_list.append(k0[0:28])
        self.d_list.append(k0[28:56])
        self.k_list.append(self.substitution(k0, self.PC2))
        for i in range(1, 17):
            c, d = [], []
            if i in [1, 2, 9, 16]:
                c = self.c_list[i - 1][1:] + self.c_list[i - 1][0:1]
                d = self.d_list[i - 1][1:] + self.d_list[i - 1][0:1]
            else:
                c = self.c_list[i - 1][2:] + self.c_list[i - 1][0:2]
                d = self.d_list[i - 1][2:] + self.d_list[i - 1][0:2]

            self.c_list.append(c)
            self.d_list.append(d)
            self.k_list.append(self.substitution(c + d, self.PC2))

    def func(self, R, key):
        """
        :param R: 每一轮的R,list
        :param key: 每一轮的K,list
        :return: 每一轮 f(R, key)
        """
        E_R = self.substitution(R, self.E)
        tmp = [(E_R[i] ^ key[i]) for i in range(0, 48)]
        C = []
        for i in range(0, 8):
            B = tmp[i * 6: (i + 1) * 6]
            row = B[0] * 2 + B[5] * 1
            column = B[1] * 8 + B[2] * 4 + B[3] * 2 + B[4] * 1

            num = self.S_BOXES[i][row][column]
            lst = []
            for j in range(4):
                lst.append(int(num % 2 != 0))
                num = num // 2
            C = C + lst[::-1]
        P = self.substitution(C, self.P)
        return P

    def init_P(self):
        """
        16次迭代
        """
        ip = self.substitution(self.X, self.IP)
        self.l_list.append(copy.deepcopy(ip[0:32]))
        self.r_list.append(copy.deepcopy(ip[32:64]))

        for i in range(1, 17):
            l = copy.deepcopy(self.l_list[-1])
            r = copy.deepcopy(self.r_list[-1])

            new_l = r
            new_r = self.func(r, self.k_list[i])
            for j in range(0, 32):
                new_r[j] = new_r[j] ^ l[j]

            self.l_list.append(new_l)
            self.r_list.append(new_r)

    def to_16(self, C=None):
        """
        :param C: 二进制序列转化为十六进制,list
        :return: C的十六进制表示,str
        """
        if C is None:
            C = self.C
        num_list = ''
        for i in range(0, len(C) // 4):
            s = i * 4
            num = C[s] * 8 + C[s + 1] * 4 + C[s + 2] * 2 + C[s + 3] * 1
            num_list += hex(num)[2:].upper()

        return num_list

    def pri_all(self):
        """
        输出每一轮的L,R,K 和最后的结果
        :return: None
        """
        print('-' * 100)
        for i in range(0, 17):
            print(f'第{i}轮:')
            print(f'L = {"".join([str(_) for _ in self.l_list[i]])}')
            print(f'R = {"".join([str(_) for _ in self.r_list[i]])}')
            print(f'K = {"".join([str(_) for _ in self.k_list[i]])}')
            print('-' * 100)

        print(f'X = {self.to_16(self.X)}, K = {self.to_16(self.K)}')
        print(f'RES = {self.to_16()}')


def str16_to_list2(hex_string):
    """
    16进制字符串转化为2进制list
    :param hex_string: 16进制字符串
    :return: 转化后的2进制list
    """
    binary_list = [bin(int(hex_digit, 16))[2:].zfill(4) for hex_digit in hex_string]
    res = []
    for item in binary_list:
        for bit in item:
            res.append(int(bit))
    return res


if __name__ == '__main__':
    X_16 = '0123456789ABCDEF'
    K_16 = '133457799BBCDFF1'

    X_2 = str16_to_list2(X_16)
    K_2 = str16_to_list2(K_16)

    d = DES(X=X_2, K=K_2)

    d.pri_all()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值