DES(Data Encryption Standard)算法

DES算法

DES(Data Encryption Standard)是迄今为止世界上最为广泛使用和流行的一种分组密码算法,它的分组长度为64bit,密钥长度为56bit,它是由美国IBM公司研制的,是早期的称作Lucifer密码的一种发展和修改。

1 前置知识

1.1 Feistel 网络

很多分组密码的结构从本质上说都是基于Feistel 网络结构。

Feistel 加密结构:

在Feistel 密码结构中,加密算法输入的是一个长度为 2 w 2w 2w的明文和密钥 K K K,将每组明文分为左右两半 L 0 , R 0 L_0,R_0 L0,R0,在进行完 n n n轮迭代之后,左右两半在合并到一起产生密文分组。算法的示意图如下:

其中第 i i i轮迭代可以表示为:
L i = R i − 1 R i = L i − 1 ⨁ F ( R i − 1 , K i ) L_i = R_{i-1} \\ R_i = L_{i-1}\bigoplus F(R_{i-1}, K_i) Li=Ri1Ri=Li1F(Ri1,Ki)
其中, K i K_i Ki是第i轮使用的密钥,由加密密钥 K K K得来。一般来说,各轮的子密钥各不相同且与 K K K不同。

Feistel 解密结构

Feistel 解密结构和加密结构在过程上是一致的,算法使用密文作为输入,但使用子密钥 K i K_i Ki的次序需要与加密过程相反。下图表示进行16轮Feistel 加密和解密的具体过程:

2 DES 算法加密步骤

下图是DES 算法加密的框架,其中明文是64bit,而密钥长56bit。

**明文处理过程:**首先是一个初始置换IP,用于重排明文分组的64bit数据。然后是具有相同功能的16轮变换,每轮变换中有置换和代换运算,第16轮变换的输出分为左右两半,并交换次序。最后再经过一个逆出事置换 I P − 1 IP^{-1} IP1(为IP的逆)从而产生64bit的密文。

**密钥使用方法:**密钥首先经过一个置换函数,然后对于加密的每一轮,通过一个左循环移位和一个置换生成一个子密钥。

2.1 初始置换

下图分别是初始置换和逆初始置换的定义:

为了更好的理解,下面是一个输入数据 M M M

截屏2022-09-17 16.29.37 ![在这里插入图片描述](https://img-blog.csdnimg.cn/d6abeabb4e104f6dbd6ea8d2aa08b3c0.png)

我们根据上述(a)对M进行变换,即 X = I P ( M ) X=IP(M) X=IP(M),可以得到以下的结果:

M 58 M_{58} M58为例子,现在它相当于是 X 1 X_1 X1,而我们再根据上述(b)对X进行逆变换,即 Y = I P − 1 ( X ) = I P − 1 ( I P ( M ) ) Y=IP^{-1}(X) = IP^{-1}(IP(M)) Y=IP1(X)=IP1(IP(M)),就可以看到M恢复了原本的顺序。

import numpy as np


def IP(M, reverse=False):
    order = None
    if reverse is False:
        order = [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]
    else:
        order = [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]
    res = np.zeros(M.shape)
    for i in range(64):
        res[i] = M[order[i] - 1]

    return res
2.2 轮结构

下图是DES加密算法的轮结构:

在左侧中,将64bit的轮输入分为各32bit的左右两半,分别标记为 L , R L,R L,R。和Feistel 网络一样,变换可以表示为:
L i = R i − 1 R i = L i − 1 ⨁ F ( R i − 1 , K i ) L_i = R_{i-1} \\ R_i = L_{i-1}\bigoplus F(R_{i-1}, K_i) Li=Ri1Ri=Li1F(Ri1,Ki)
其中 K i K_i Ki为48bit,函数F的具体过程如下图所示:

2.2.1 E表(扩展/置换)

轮输入的右半部分 R R R首先要被扩展为48bit,扩展的过程如下图所示:

原本数据 R R R为32位,扩展后数据 R ′ R^\prime R为48bit,以 R ′ R^\prime R的第一行为例子,第一行的第一个元素为 R 32 R_{32} R32,而最后一个元素为 R 5 R_5 R5 ,以此达到扩展的目的。

import numpy as np


def Expand(M):
    order = [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]
    res = np.zeros(48)
    for i in range(48):
        res[i] = M[order[i] - 1]
    
    return res
2.2.2 S盒(代换/选择)

经过扩展的48bit和子密钥 K i K_i Ki异或,然后分为8组6bit的数据,分别经过S盒,最后合并输出32bit。F中的代换由8个S盒构成,每一个S盒的输出为6bit,输出为4bit,最终形成48bit输入,32bit输出。8个S盒的定义如下:

对于每一个盒 S i S_i Si,其6bit输入中,第1个bit和第6个bit形成一个2位二进制数,用来选择 S i S_i Si的行,而6bit输入的中间4bit构成一个4位的二进制数,用来选择 S i S_i Si的列。行列选定后,交叉位置的十位制数转化为4位二进制数即为 S i S_i Si的输出。

比如,如果 S 1 S_1 S1的输入是011001,那么选择第2行(01),第12列(1100)的数字9,再将其转化为二进制1001,就得到了结果。

def S(M):
    order = [
        [[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]],

        [[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]],

        [[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]],

        [[7, 13, 14,  3,  0,  6,  9, 10,  1,  2,  8,  5, 11,  12,  4, 15],
            [13,  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]],

        [[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]],


        [[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,  3,  2, 12,  9,  5, 15, 10, 11, 14,  1,  7,  6,  0,  8, 13]],

        [[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]],

        [[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]]
    ]
    res = []
    for i in range(8):
        index_row = M[6*i]*2 + M[6*i + 5]*1
        index_col = M[6*i + 1]*8 + M[6*i + 2]*4 + M[6*i + 3]*2 + M[6*i + 4]*1
        num = order[i][index_row][index_col]
        num_bin = bin(num)[2:]
        for j in range(4):
            res.append( int(num_bin[j]) )
    res = np.array(res)

    return res
2.2.3 P盒(置换)

和上述初始置换基本一致,在此只给出代换表,不再赘述。

def P(M):
    order = [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]
    res = np.zeros(32)
    for i in range(32):
        res[i] = M[order[i] - 1]
    
    return res
2.3 密钥生成

输入的64bit密钥先经过一个置换运算,和上述置换运算基本一致,置换表如下。在此处需要说明为什么输入的是64bit而非56bit,这是因为在一般使用情况下,密钥会带有8bit的奇偶校验位,所以输入的密钥长度为8+56=64bit,在经过PC-1置换之后得到的密钥就变成了56bit。

置换之后将56bit的密钥分为28bit的两部分 C 0 , D 0 C_0,D_0 C0,D0。在第i轮对 C i − 1 , D i − 1 C_{i-1},D_{i-1} Ci1,Di1进行左循环移动,具体移动位数参考下表,移位后的结果作为下一轮求解子密钥的输入,同时也作为置换选择 2 的输入。

通过置换选择2产生的48bit的 K i K_i Ki,作为 F ( R i − 1 , K i ) F(R_{i-1},K_i) F(Ri1,Ki)输入,其中置换选择2定义为:

def PC_1(K):
    PC_1 = [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]
    key = np.zeros(56)
    for i in range(56):
        key[i] = K[PC_1[i] - 1]

    return key

def key_generate(K, num_round):
    key_left = K[:28]
    key_right = K[28:]
    shift = [1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1]
    num_move = shift[num_round - 1]
    key_left = np.hstack((key_left[num_move:], key_left[:num_move]))
    key_right = np.hstack((key_right[num_move:], key_right[:num_move]))
    key = key_left + key_right
    
    PC_2 = [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]
    key_i = np.zeros(48)
    for i in range(48):
        key_i[i] = key[PC_2[i] - 1]
    
    return key, key_i
2.4 算法实现

下面的代码实现,绝大部分的变量类型是np.array,经过考虑之后发现str类型应该更加方便灵活且运行速度快,所以仅仅作为思路参考,不适合使用。

import numpy as np
import math

def IP(M, reverse=False):
    '''
    :param M: 64bit的密文
    :param reverse: 是否为逆变换,True是逆变化
    :return: 经过IP变化之后的64bit密文
    '''
    order = None
    if reverse is False:
        order = [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]
    else:
        order = [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]
    res = np.zeros(M.shape)
    for i in range(64):
        res[i] = M[order[i] - 1]

    return res

def Expand(M):
    '''
    :param M: 32bit密文
    :return: 经过E变化之后的48bit密文
    '''
    order = [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]
    res = np.zeros(48)
    for i in range(48):
        res[i] = M[order[i] - 1]

    return res

def Xor(a, b):
    '''
    a, b的长度需要相等
    :return:a^b
    '''
    if a.shape[0] != b.shape[0]:
        raise Exception('Error with : a, b are not the same length.')
    res = np.zeros(a.shape)
    for i in range(a.shape[0]):
        res[i] = int(a[i]) ^ int(b[i])

    return res

def S(M):
    '''
    :param M: 48bit密文
    :return:经过S盒的32bit密文
    '''
    order = [
        [[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]],

        [[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]],

        [[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]],

        [[7, 13, 14,  3,  0,  6,  9, 10,  1,  2,  8,  5, 11,  12,  4, 15],
            [13,  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]],

        [[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]],


        [[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,  3,  2, 12,  9,  5, 15, 10, 11, 14,  1,  7,  6,  0,  8, 13]],

        [[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]],

        [[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]]
    ]
    res = []
    for i in range(8):
        index_row = int(M[6*i]*2 + M[6*i + 5]*1)
        index_col = int(M[6*i + 1]*8 + M[6*i + 2]*4 + M[6*i + 3]*2 + M[6*i + 4]*1)
        num = order[i][index_row][index_col]
        num_bin = bin(num)[2:]
        for j in range(4-len(num_bin)):
            num_bin = '0' + num_bin
        for j in range(4):
            res.append( int(num_bin[j]) )
    res = np.array(res)

    return res

def P(M):
    '''
    :param M: 32bit密文
    :return: 经过P置换之后的32bit密文
    '''
    order = [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]
    res = np.zeros(32)
    for i in range(32):
        res[i] = M[order[i] - 1]

    return res

def PC_1(K):
    '''
    :param K: 64bit密文(含奇偶校验位)
    :return: 经过初始置换的56bit密文
    '''
    PC_1 = [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]
    key = np.zeros(56)
    for i in range(56):
        key[i] = K[PC_1[i] - 1]

    return key

def key_generate(K, num_round):
    '''
    :param K: 56bit密文
    :param num_round: 轮数
    :return: 下轮的56bit密钥、本轮的48bit密钥
    '''
    key_left = K[:28]
    key_right = K[28:]
    shift = [1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1]
    num_move = shift[num_round - 1]
    key_left = np.hstack((key_left[num_move:], key_left[:num_move]))
    key_right = np.hstack((key_right[num_move:], key_right[:num_move]))
    key = np.hstack((key_left, key_right))

    PC_2 = [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]
    key_i = np.zeros(48)
    for i in range(48):
        key_i[i] = key[PC_2[i] - 1]

    return key, key_i

def key_create(key_message):
    '''
    :param key_message: 密钥字符串
    :return: 64bit密钥
    '''
    key = []
    for word in key_message:
        word_bin = bin(ord(word))[2:]
        if len(word_bin) > 7:
            word_bin = word_bin[:7]
        else:
            for i in range(7 - len(word_bin)):
                word_bin = '0' + word_bin
        count = 0
        for i in range(len(word_bin)):
            if word_bin[i] == '1':
                count += 1
        if count % 2 == 0:
            word_bin += '0'
        else:
            word_bin += '1'
        for i in range(len(word_bin)):
            key.append(int(word_bin[i]))
    if len(key) > 64:
        key = key[:64]
    else:
        for i in range(64 - len(key)):
            key = [0] + key
    res = np.array(key)

    return res

def data_group(data_message):
    '''
    :param data_message: 需要加密的字符串
    :return: 64bit分组后的data列表
    '''
    data = ''
    for word in data_message:
        word_bin = bin(ord(word))[2:]
        if len(word_bin) > 8: # 如果message为英文字符串的话一般不会出现这种情况,也就不会出现信息缺失的问题
            raise Exception('Eorro with : ' + word + ' > 8bit')
        else:
            for i in range(8 - len(word_bin)):
                word_bin = '0' + word_bin
        data = data + word_bin
    res = []
    for i in range(math.floor(len(data) / 64)):
        temp = []
        for j in range(64):
            temp.append(int(data[64*i + j]))
        res.append(temp)
    temp = []
    for i in range(len(data) % 64):
        temp.append( int(data[math.floor(len(data) / 64)*64 + i]) )
    for i in range(64 - len(temp)):
        temp.append(0)
    res.append(temp)
    res = np.array(res)

    return res


def encrypt(data_message, key_message):
    '''
    :param data: 需要加密的64bit数据
    :param key_message: 字符串密钥
    :return: 密文
    '''
    data = data_group(data_message)
    key = key_create(key_message)
    res = ''

    key_before = PC_1(key)
    for i in range(data.shape[0]):
        data_before = IP(data[i]) # 初始置换
        for j in range(16):
            key_before, key_j = key_generate(K=key_before, num_round=j+1)
            data_left = data_before[:32]
            data_right = data_before[32:]
            data_temp = Expand(data_right)
            data_temp = Xor(data_temp, key_j)
            data_temp = S(data_temp)
            data_temp = P(data_temp)
            data_right = Xor(data_left, data_temp)
            data_before = np.hstack((data_right, data_left))
        temp = IP(data_before, reverse=True)
        for j in range(64):
            res = res + str(int(temp[j]))

    return res

print(encrypt(data_message='life is fantastic.', key_message='HELLO'))
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值