DES加解密算法详解(py+tkinter实现可视化加密软件)

DES简介

DES全称为Data Encryption Standard,即数据加密标准,是一种使用密钥加密的块算法,1977年被美国联邦政府的国家标准局确定为联邦资料处理标准(FIPS),并授权在非密级政府通信中使用,随后该算法在国际上广泛流传开来。

DES的基本原则

DES设计中使用了分组密码设计的两个原则:混淆(confusion)和扩散(diffusion),其目的是抗击敌手对密码系统的统计分析。混淆是使密文的统计特性与密钥的取值之间的关系尽可能复杂化,以使密钥和明文以及密文之间的依赖性对密码分析者来说是无法利用的。扩散的作用就是将每一位明文的影响尽可能迅速地作用到较多的输出密文位中,以便在大量的密文中消除明文的统计结构,并且使每一位密钥的影响尽可能迅速地扩展到较多的密文位中,以防对密钥进行逐段破译。

加密算法步骤

(1)基础知识

首先,介绍有关DES的基础知识,DES是经典分组密码,其中需要加密的明文长度为64bit
密钥长度为64bit(其中8位作为校验位,密钥实际长度为56bit)

(2)整体流程

DES是典型的Feistal密码结构,设计密码的两个最基本方法就是扩散混淆
请添加图片描述首先,将64bit的明文分成左右两个部分,经过IP置换后进入循环。本轮右半部分明文直接作为下一轮明文的左半部分输入,本轮右半部分明文和第一轮子密钥在f的作用下的输入与本轮左半部分明文异或之后的结果作为下一轮明文的右半部分。

L[i]=R[i-1]
R[i]=L[i-1]^F(R[i-1],k[i])

如此循环16轮,需要16个轮密钥,将16轮变换后得到比特串左右两半调换位置,对调换完毕的新的比特串进行IP逆置换得到加密后的密文。

(3)轮密钥生成算法

请添加图片描述初始密钥为64bit,首先经过PC-1置换,提取出有效的56bit密钥,将56bit的有效密钥平均分成左右两个28位的比特串,将两个28位比特串循环左移位后组合成56位比特串,将此56位的比特串作为PC-2的输入,压缩后得到48位比特串即位本轮子密钥的输出。如此循环直至产生16轮子密钥。
具体的移位规则是除了第1,2,9,16轮左移一位,其余轮都是左移两位。

(4)轮结构

请添加图片描述

L[i]=R[i-1]
R[i]=L[i-1]^F(R[i-1],k[i])

解释F函数中的一些操作, 将右半边32位比特串作为E盒的输入,扩展得到48位比特串再与生成的本轮子密钥异或,输出的结果作为输入进入S盒进行压缩,重新压缩得到32位比特串与L进行异或,异或后的结果就是R。

S盒的操作:
DES中共有8个S盒,每个S盒是一个4*16的矩阵,将输入的48位比特串分为8组,每组6bit作为输入进入对应的S盒,将每组6bit的首位S[0]、末位S[5]构成的二进制数作为S盒的行号,中间的4bit(S[1]~S[4])作为S盒的列号,根据行号、列号查找对应S盒对应的值(一般是十进制)转换成4位二进制数输出,这样没一组的6bit就被压缩成4bit,整个48位的比特串也被压缩为32位。

(5)其余置换

以初始IP置换为例。

请添加图片描述 表中的数字代表新数据中此位置的数据在原数据中的位置,即原数据块的第58位放到新数据的第1位,第50位放到第2位,……依此类推,第7位放到第64位。置换后的数据分为L0和R0两部分,L0为新数据的左32位,R0为新数据的右32位。
其余置换于此类似。

DES 解密算法

DES解密算法与加密算法类似,唯一不同的是,颠倒了轮密钥的次序,即加密的第16轮密钥作为解密的第1轮密钥、加密第15轮密钥作为解密的第2轮密钥。

算法实现

了解完DES的基本原理和步骤之后,更重要的是代码实现。
直接上代码

声明:本代码不包含tkinter实现可视化部分,后序会通过百度云分享。

print("DES 加密系统:")
choose=str(input('请选择加密(E)/解密(D):'))
#IP置换
def IP(a):
    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]
    return [a[x - 1] for x in ip]
#进行PC-2置换
def to_PC2(round_key):
    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]
    return [round_key[x - 1] for x in pc2]
#进行PC-1置换
def to_PC1(round_key):
    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]
    return [round_key[x-1] for x in pc1]
#E盒扩展
def to_E(r_E):
    assert len(r_E) == 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]
    return [r_E[x - 1] for x in e]
#P盒置换
def to_P(r_S):
    assert len(r_S) == 32
    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]
    return [r_S[x - 1] for x in p]
#IP逆置换
def IPS(a):
    fp = [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]
    return [a[x - 1] for x in fp]
#s1
List_S1=[]

List_S1.append(14),List_S1.append(4),List_S1.append(13),List_S1.append(1),List_S1.append(2),List_S1.append(15)

List_S1.append(11),List_S1.append(8),List_S1.append(3),List_S1.append(10),List_S1.append(6),List_S1.append(12)

List_S1.append(5),List_S1.append(9),List_S1.append(0),List_S1.append(7)

List_S1.append(0),List_S1.append(15),List_S1.append(7),List_S1.append(4),List_S1.append(14),List_S1.append(2)

List_S1.append(13),List_S1.append(1),List_S1.append(10),List_S1.append(6),List_S1.append(12),List_S1.append(11)

List_S1.append(9),List_S1.append(5),List_S1.append(3),List_S1.append(8)

List_S1.append(4),List_S1.append(1),List_S1.append(14),List_S1.append(8),List_S1.append(13),List_S1.append(6)

List_S1.append(2),List_S1.append(11),List_S1.append(15),List_S1.append(12),List_S1.append(9),List_S1.append(7)

List_S1.append(3),List_S1.append(10),List_S1.append(5),List_S1.append(0)

List_S1.append(15),List_S1.append(12),List_S1.append(8),List_S1.append(2),List_S1.append(4),List_S1.append(9)

List_S1.append(1),List_S1.append(7),List_S1.append(5),List_S1.append(11),List_S1.append(3),List_S1.append(14)

List_S1.append(10),List_S1.append(0),List_S1.append(6),List_S1.append(13)

#s2
List_s2=[]

List_s2.append(15),List_s2.append(1),List_s2.append(8),List_s2.append(14),List_s2.append(6),List_s2.append(11)

List_s2.append(3),List_s2.append(4),List_s2.append(9),List_s2.append(7),List_s2.append(2),List_s2.append(13)

List_s2.append(12),List_s2.append(0),List_s2.append(5),List_s2.append(10)

List_s2.append(3),List_s2.append(13),List_s2.append(4),List_s2.append(7),List_s2.append(15),List_s2.append(2)

List_s2.append(8),List_s2.append(14),List_s2.append(12),List_s2.append(0),List_s2.append(1),List_s2.append(10)

List_s2.append(6),List_s2.append(9),List_s2.append(11),List_s2.append(5)

List_s2.append(0),List_s2.append(14),List_s2.append(7),List_s2.append(11),List_s2.append(10),List_s2.append(4)

List_s2.append(13),List_s2.append(1),List_s2.append(5),List_s2.append(8),List_s2.append(12),List_s2.append(6)

List_s2.append(9),List_s2.append(3),List_s2.append(2),List_s2.append(15)

List_s2.append(13),List_s2.append(8),List_s2.append(10),List_s2.append(1),List_s2.append(3),List_s2.append(15)

List_s2.append(4),List_s2.append(2),List_s2.append(11),List_s2.append(6),List_s2.append(7),List_s2.append(12)

List_s2.append(0),List_s2.append(5),List_s2.append(14),List_s2.append(9)

#s3
List_s3=[]

List_s3.append(10),List_s3.append(0),List_s3.append(9),List_s3.append(14),List_s3.append(6),List_s3.append(3)

List_s3.append(15),List_s3.append(5),List_s3.append(1),List_s3.append(13),List_s3.append(12),List_s3.append(7)

List_s3.append(11),List_s3.append(4),List_s3.append(2),List_s3.append(8)

List_s3.append(13),List_s3.append(7),List_s3.append(0),List_s3.append(9),List_s3.append(3),List_s3.append(4)

List_s3.append(6),List_s3.append(10),List_s3.append(2),List_s3.append(8),List_s3.append(5),List_s3.append(14)

List_s3.append(12),List_s3.append(11),List_s3.append(15),List_s3.append(1)

List_s3.append(13),List_s3.append(6),List_s3.append(4),List_s3.append(9),List_s3.append(8),List_s3.append(15)

List_s3.append(3),List_s3.append(0),List_s3.append(11),List_s3.append(1),List_s3.append(2),List_s3.append(12)

List_s3.append(5),List_s3.append(10),List_s3.append(14),List_s3.append(7)

List_s3.append(1),List_s3.append(10),List_s3.append(13),List_s3.append(0),List_s3.append(6),List_s3.append(9)

List_s3.append(8),List_s3.append(7),List_s3.append(4),List_s3.append(15),List_s3.append(14),List_s3.append(3),List_s3.append(11),List_s3.append(5),List_s3.append(2),List_s3.append(12)

#s4
List_s4=[]

List_s4.append(7),List_s4.append(13),List_s4.append(14),List_s4.append(3),List_s4.append(0),List_s4.append(6),List_s4.append(9)

List_s4.append(10),List_s4.append(1),List_s4.append(2),List_s4.append(8),List_s4.append(5),List_s4.append(11),List_s4.append(12)

List_s4.append(4),List_s4.append(15)

List_s4.append(13),List_s4.append(8),List_s4.append(11),List_s4.append(5),List_s4.append(6),List_s4.append(15),List_s4.append(0)

List_s4.append(3),List_s4.append(4),List_s4.append(7),List_s4.append(2),List_s4.append(12),List_s4.append(1),List_s4.append(10)

List_s4.append(14),List_s4.append(9)

List_s4.append(10),List_s4.append(6),List_s4.append(9),List_s4.append(0),List_s4.append(12),List_s4.append(11),List_s4.append(7)

List_s4.append(13),List_s4.append(15),List_s4.append(1),List_s4.append(3),List_s4.append(14),List_s4.append(5),List_s4.append(2)

List_s4.append(8),List_s4.append(4)

List_s4.append(3),List_s4.append(15),List_s4.append(0),List_s4.append(6),List_s4.append(10),List_s4.append(1),List_s4.append(13)

List_s4.append(8),List_s4.append(9),List_s4.append(4),List_s4.append(5),List_s4.append(11),List_s4.append(12),List_s4.append(7)

List_s4.append(2),List_s4.append(14)

#s5
List_s5=[]

List_s5.append(2),List_s5.append(12),List_s5.append(4),List_s5.append(1),List_s5.append(7),List_s5.append(10),List_s5.append(11),List_s5.append(6)

List_s5.append(8),List_s5.append(5),List_s5.append(3),List_s5.append(15),List_s5.append(13),List_s5.append(0),List_s5.append(14),List_s5.append(9)

List_s5.append(14),List_s5.append(11),List_s5.append(2),List_s5.append(12),List_s5.append(4),List_s5.append(7),List_s5.append(13),List_s5.append(1)

List_s5.append(5),List_s5.append(0),List_s5.append(15),List_s5.append(10),List_s5.append(3),List_s5.append(9),List_s5.append(8),List_s5.append(6)

List_s5.append(4),List_s5.append(2),List_s5.append(1),List_s5.append(11),List_s5.append(10),List_s5.append(13),List_s5.append(7),List_s5.append(8)

List_s5.append(15),List_s5.append(9),List_s5.append(12),List_s5.append(5),List_s5.append(6),List_s5.append(3),List_s5.append(0),List_s5.append(14)

List_s5.append(11),List_s5.append(8),List_s5.append(12),List_s5.append(7),List_s5.append(1),List_s5.append(14),List_s5.append(2),List_s5.append(13)

List_s5.append(6),List_s5.append(15),List_s5.append(0),List_s5.append(9),List_s5.append(10),List_s5.append(4),List_s5.append(5),List_s5.append(3)

#s6
List_s6=[]

List_s6.append(12),List_s6.append(1),List_s6.append(10),List_s6.append(15),List_s6.append(9),List_s6.append(2),List_s6.append(6),List_s6.append(8)

List_s6.append(0),List_s6.append(13),List_s6.append(3),List_s6.append(4),List_s6.append(14),List_s6.append(7),List_s6.append(5),List_s6.append(11)

List_s6.append(10),List_s6.append(15),List_s6.append(4),List_s6.append(2),List_s6.append(7),List_s6.append(12),List_s6.append(9),List_s6.append(5)

List_s6.append(6),List_s6.append(1),List_s6.append(13),List_s6.append(14),List_s6.append(0),List_s6.append(11),List_s6.append(3),List_s6.append(8)

List_s6.append(9),List_s6.append(14),List_s6.append(15),List_s6.append(5),List_s6.append(2),List_s6.append(8),List_s6.append(12),List_s6.append(3)

List_s6.append(7),List_s6.append(0),List_s6.append(4),List_s6.append(10),List_s6.append(1),List_s6.append(13),List_s6.append(11),List_s6.append(6)

List_s6.append(4),List_s6.append(3),List_s6.append(2),List_s6.append(12),List_s6.append(9),List_s6.append(5),List_s6.append(15),List_s6.append(10)

List_s6.append(11),List_s6.append(14),List_s6.append(1),List_s6.append(7),List_s6.append(6),List_s6.append(0),List_s6.append(8),List_s6.append(13)

#s7
List_s7=[]
List_s7.append(4),List_s7.append(11),List_s7.append(2),List_s7.append(14),List_s7.append(15),List_s7.append(0),List_s7.append(8),List_s7.append(13)

List_s7.append(3),List_s7.append(12),List_s7.append(9),List_s7.append(7),List_s7.append(5),List_s7.append(10),List_s7.append(6),List_s7.append(1)

List_s7.append(13),List_s7.append(0),List_s7.append(11),List_s7.append(7),List_s7.append(4),List_s7.append(9),List_s7.append(1),List_s7.append(10)

List_s7.append(14),List_s7.append(3),List_s7.append(5),List_s7.append(12),List_s7.append(2),List_s7.append(15),List_s7.append(8),List_s7.append(6)

List_s7.append(1),List_s7.append(4),List_s7.append(11),List_s7.append(13),List_s7.append(12),List_s7.append(3),List_s7.append(7),List_s7.append(14)

List_s7.append(10),List_s7.append(15),List_s7.append(6),List_s7.append(8),List_s7.append(0),List_s7.append(5),List_s7.append(9),List_s7.append(2)

List_s7.append(6),List_s7.append(11),List_s7.append(13),List_s7.append(8),List_s7.append(1),List_s7.append(4),List_s7.append(10),List_s7.append(7)

List_s7.append(9),List_s7.append(5),List_s7.append(0),List_s7.append(15),List_s7.append(14),List_s7.append(2),List_s7.append(3),List_s7.append(12)

#s8
List_s8=[]
List_s8.append(13),List_s8.append(2),List_s8.append(8),List_s8.append(4),List_s8.append(6),List_s8.append(15),List_s8.append(11),List_s8.append(1)

List_s8.append(10),List_s8.append(9),List_s8.append(3),List_s8.append(14),List_s8.append(5),List_s8.append(0),List_s8.append(12),List_s8.append(7)

List_s8.append(1),List_s8.append(15),List_s8.append(13),List_s8.append(8),List_s8.append(10),List_s8.append(3),List_s8.append(7),List_s8.append(4)

List_s8.append(12),List_s8.append(5),List_s8.append(6),List_s8.append(11),List_s8.append(0),List_s8.append(14),List_s8.append(9),List_s8.append(2)

List_s8.append(7),List_s8.append(11),List_s8.append(4),List_s8.append(1),List_s8.append(9),List_s8.append(12),List_s8.append(14),List_s8.append(2)

List_s8.append(0),List_s8.append(6),List_s8.append(10),List_s8.append(13),List_s8.append(15),List_s8.append(3),List_s8.append(5),List_s8.append(8)

List_s8.append(2),List_s8.append(1),List_s8.append(14),List_s8.append(7),List_s8.append(4),List_s8.append(10),List_s8.append(8),List_s8.append(13)

List_s8.append(15),List_s8.append(12),List_s8.append(9),List_s8.append(0),List_s8.append(3),List_s8.append(5),List_s8.append(6),List_s8.append(11)
if choose=='E':
    a = str(input('请输入8位明文:'))
    b = ""
    # 将输入的明文转换成二进制
    for i in a:
        t = ord(i)
        t = bin(t)
        t = t.replace("0b", "0")
        # print(t)
        b += t
    #a=str(input('请输入密文的十六进制表示:'))

    # 将输入的密钥转换成二进制
    k = str(input('请输入8位密钥:'))
    key = ""
    for i in k:
        t = ord(i)
        t = bin(t)
        t = t.replace("0b", "0")
        if (len(t) < 8):
            t = str(0) * (8 - len(t)) + t
        key += t

    #进行IP置换
    b_ip = IP(b)
    b = ""
    for i in range(0, len(b_ip)):
        b += str(b_ip[i])

    l = [0] * 70
    r = [0] * 70

    l[0] = b[0:32]
    r[0] = b[32:64]

    #进行PC-1置换
    d = to_PC1(key)
    key = ""
    for i in range(0, len(d)):
        key += str(d[i])

    l_key = [0] * 30
    r_key = [0] * 30

    l_key[0] = key[0:28]
    r_key[0] = key[28:56]
    cnt_r = 1  # 轮数计数
    while cnt_r <= 16:
        l[cnt_r] = r[cnt_r - 1]
        l_k = str(l_key[cnt_r - 1])
        r_k = str(r_key[cnt_r - 1])
        if (cnt_r == 1 or cnt_r == 2 or cnt_r == 9 or cnt_r == 16):
            l_key[cnt_r] = l_k[1:] + l_k[:1]
            r_key[cnt_r] = r_k[1:] + r_k[:1]
        else:
            l_key[cnt_r] = l_k[2:] + l_k[:2]
            r_key[cnt_r] = r_k[2:] + r_k[:2]
        round_keys = l_key[cnt_r] + r_key[cnt_r] #生成轮密钥
        # PC-2置换
        round_keys = to_PC2(round_keys)
        round_key = ""
        for i in range(0, len(round_keys)):
            round_key += round_keys[i]
        # E盒扩展
        r_ms = to_E(r[cnt_r - 1])  # E盒扩展后的右半边明文
        r_m = ""
        for i in range(0, len(r_ms)):
            r_m += r_ms[i]
        x_or = ""
        #得到异或值
        for i in range(0, 48):
            c = int(r_m[i]) ^ int(round_key[i])
            x_or += str(c)

        gou_cnt = 0
        gou_cnt2 = 0
        s_out = ""
        while gou_cnt < 48:
            gou_cnt2 += 1
            to_s = x_or[gou_cnt:gou_cnt + 6]
            gou_cnt += 6
            s_h = to_s[0] + to_s[-1]
            s_l = to_s[1:5]
            s_hv = 0
            s_lv = 0
            val = 1
            # 转换成十进制
            for i in range(len(s_h) - 1, -1, -1):
                s_hv += int(s_h[i]) * val
                val *= 2
            val = 1
            for i in range(len(s_l) - 1, -1, -1):
                s_lv += int(s_l[i]) * val
                val *= 2
            if (gou_cnt2 == 1):
                s_v = List_S1[s_hv * 16 + s_lv]
                s_vnum = bin(s_v)
                s_vnum = s_vnum.replace("0b", "")
                if len(s_vnum) < 4:
                    s_vnums = "0" * (4 - len(s_vnum))
                    s_vnums += s_vnum
                else:
                    s_vnums = s_vnum
                s_out += s_vnums
            elif (gou_cnt2 == 2):
                s_v = List_s2[s_hv * 16 + s_lv]
                s_vnum = bin(s_v)
                s_vnum = s_vnum.replace("0b", "")
                if len(s_vnum) < 4:
                    s_vnums = "0" * (4 - len(s_vnum))
                    s_vnums += s_vnum
                else:
                    s_vnums = s_vnum
                s_out += s_vnums
            elif (gou_cnt2 == 3):
                s_v = List_s3[s_hv * 16 + s_lv]
                s_vnum = bin(s_v)
                s_vnum = s_vnum.replace("0b", "")
                if len(s_vnum) < 4:
                    s_vnums = "0" * (4 - len(s_vnum))
                    s_vnums += s_vnum
                else:
                    s_vnums = s_vnum
                s_out += s_vnums
            elif (gou_cnt2 == 4):
                s_v = List_s4[s_hv * 16 + s_lv]
                s_vnum = bin(s_v)
                s_vnum = s_vnum.replace("0b", "")
                if len(s_vnum) < 4:
                    s_vnums = "0" * (4 - len(s_vnum))
                    s_vnums += s_vnum
                else:
                    s_vnums = s_vnum
                s_out += s_vnums
            elif (gou_cnt2 == 5):
                s_v = List_s5[s_hv * 16 + s_lv]
                s_vnum = bin(s_v)
                s_vnum = s_vnum.replace("0b", "")
                if len(s_vnum) < 4:
                    s_vnums = "0" * (4 - len(s_vnum))
                    s_vnums += s_vnum
                else:
                    s_vnums = s_vnum
                s_out += s_vnums
            elif (gou_cnt2 == 6):
                s_v = List_s6[s_hv * 16 + s_lv]
                s_vnum = bin(s_v)
                s_vnum = s_vnum.replace("0b", "")
                if len(s_vnum) < 4:
                    s_vnums = "0" * (4 - len(s_vnum))
                    s_vnums += s_vnum
                else:
                    s_vnums = s_vnum
                s_out += s_vnums
            elif (gou_cnt2 == 7):
                s_v = List_s7[s_hv * 16 + s_lv]
                s_vnum = bin(s_v)
                s_vnum = s_vnum.replace("0b", "")
                if len(s_vnum) < 4:
                    s_vnums = "0" * (4 - len(s_vnum))
                    s_vnums += s_vnum
                else:
                    s_vnums = s_vnum
                s_out += s_vnums
            elif (gou_cnt2 == 8):
                s_v = List_s8[s_hv * 16 + s_lv]
                s_vnum = bin(s_v)
                s_vnum = s_vnum.replace("0b", "")
                if len(s_vnum) < 4:
                    s_vnums = "0" * (4 - len(s_vnum))
                    s_vnums += s_vnum
                else:
                    s_vnums = s_vnum
                s_out += s_vnums
        s_out = to_P(s_out)
        s_outs = ""
        for i in range(0, len(s_out)):
            s_outs += s_out[i]

        l_s = l[cnt_r - 1]

        r[cnt_r] = ""
        for i in range(0, len(l_s)):
            r[cnt_r] += str(int(s_outs[i]) ^ int(l_s[i]))
        cnt_r += 1
    secret = ""
    secret = r[16] + l[16]
    secret_s = IPS(secret)
    secret_ss = ""
    for i in range(0, len(secret_s)):
        secret_ss += str(secret_s[i])

    print(secret_ss)

    i_tobase = 0
    secret_tobase = ""
    while i_tobase < len(secret_ss):
        group_tobase = secret_ss[i_tobase:i_tobase + 4]
        i_tobase += 4
        p = 1
        ans = 0
        for x in range(len(group_tobase) - 1, -1, -1):
            ans += (ord(group_tobase[x]) - ord('0')) * p
            p *= 2
        if ans >= 10:
            ans = chr(ord('A') + (ans - 10))
        secret_tobase += str(ans)
        if (i_tobase % 8 == 0):
            secret_tobase += " "
    print(secret_tobase)
elif choose=='D':
    b=""
    #b = str(input('请输入密文:'))
    c=str(input('请输入密文的十六进制表示:'))
    group_hex = ""
    i = 0
    anss = ""
    while i < len(c):
        group_hex = c[i:i + 2]
        i += 2
        val = 1
        ans = 0
        for x in range(len(group_hex) - 1, -1, -1):
            if (group_hex[x] >= 'A' and group_hex[x] <= 'F'):
                p = ord(group_hex[x]) - ord('A') + 10
            else:
                p = ord(group_hex[x]) - ord('0')
            ans += val * p
            val *= 16
        ans = bin(ans)
        ans = ans.replace('0b', "")
        if (len(ans) < 8):
            for y in range(0, 8 - len(ans)):
                ans = str("0") + ans
        #print(ans)
        b += ans
        # print(group_hex)
    #print(b)
    # 将输入的密钥转换成二进制
    k = str(input('请输入8位密钥:'))
    key = ""
    for i in k:
        t = ord(i)
        t = bin(t)
        t = t.replace("0b", "0")
        if (len(t) < 8):
            t = str(0) * (8 - len(t)) + t
        key += t
    b_ip = IP(b)
    b = ""
    for i in range(0, len(b_ip)):
        b += str(b_ip[i])

    l = [0] * 70
    r = [0] * 70

    l[0] = b[0:32]
    r[0] = b[32:64]
    d = to_PC1(key)
    key = ""
    for i in range(0, len(d)):
        key += str(d[i])

    l_key = [0] * 30
    r_key = [0] * 30

    l_key[0] = key[0:28]
    r_key[0] = key[28:56]
    cnt_k=1
    r_ks=[]
    while cnt_k<=16:
        l_k = str(l_key[(cnt_k - 1)])
        r_k = str(r_key[(cnt_k - 1)])
        if (cnt_k == 1 or cnt_k == 2 or cnt_k == 9 or cnt_k == 16):
            l_key[(cnt_k)] = l_k[1:] + l_k[:1]
            r_key[(cnt_k)] = r_k[1:] + r_k[:1]
        else:
            l_key[(cnt_k)] = l_k[2:] + l_k[:2]
            r_key[(cnt_k)] = r_k[2:] + r_k[:2]
        round_keys = l_key[(cnt_k)] + r_key[(cnt_k)]
        r_ks.append(round_keys)
        cnt_k+=1
    cnt_r = 1  # 轮数计数
    while cnt_r <= 16:
        l[cnt_r] = r[cnt_r - 1]
        l_k = str(l_key[(cnt_r - 1)])
        r_k = str(r_key[(cnt_r - 1)])
        if (cnt_r == 1 or cnt_r == 2 or cnt_r == 9 or cnt_r == 16):
            l_key[(cnt_r)] = l_k[1:] + l_k[:1]
            r_key[(cnt_r)] = r_k[1:] + r_k[:1]
        else:
            l_key[(cnt_r)] = l_k[2:] + l_k[:2]
            r_key[(cnt_r)] = r_k[2:] + r_k[:2]
        round_keys = r_ks[16-cnt_r]
        # PC-2置换
        round_keys = to_PC2(round_keys)
        round_key = ""
        for i in range(0, len(round_keys)):
            round_key += round_keys[i]
        #print(f"k{16-cnt_r}:{round_key}")
        # E盒扩展
        r_ms = to_E(r[cnt_r - 1])  # E盒扩展后的右半边明文
        r_m = ""
        for i in range(0, len(r_ms)):
            r_m += r_ms[i]
        x_or = ""
        for i in range(0, 48):
            c = int(r_m[i]) ^ int(round_key[i])
            x_or += str(c)
        gou_cnt = 0
        gou_cnt2 = 0
        s_out = ""
        while gou_cnt < 48:
            gou_cnt2 += 1
            to_s = x_or[gou_cnt:gou_cnt + 6]
            # print(to_s)
            gou_cnt += 6
            s_h = to_s[0] + to_s[-1]
            s_l = to_s[1:5]
            s_hv = 0
            s_lv = 0
            val = 1
            # 转换成十进制
            for i in range(len(s_h) - 1, -1, -1):
                s_hv += int(s_h[i]) * val
                val *= 2
            val = 1
            for i in range(len(s_l) - 1, -1, -1):
                s_lv += int(s_l[i]) * val
                val *= 2
            if (gou_cnt2 == 1):
                s_v = List_S1[s_hv * 16 + s_lv]
                s_vnum = bin(s_v)
                s_vnum = s_vnum.replace("0b", "")
                if len(s_vnum) < 4:
                    s_vnums = "0" * (4 - len(s_vnum))
                    s_vnums += s_vnum
                else:
                    s_vnums = s_vnum
                s_out += s_vnums
            elif (gou_cnt2 == 2):
                s_v = List_s2[s_hv * 16 + s_lv]
                s_vnum = bin(s_v)
                s_vnum = s_vnum.replace("0b", "")
                if len(s_vnum) < 4:
                    s_vnums = "0" * (4 - len(s_vnum))
                    s_vnums += s_vnum
                else:
                    s_vnums = s_vnum
                s_out += s_vnums
            elif (gou_cnt2 == 3):
                s_v = List_s3[s_hv * 16 + s_lv]
                s_vnum = bin(s_v)
                s_vnum = s_vnum.replace("0b", "")
                if len(s_vnum) < 4:
                    s_vnums = "0" * (4 - len(s_vnum))
                    s_vnums += s_vnum
                else:
                    s_vnums = s_vnum
                s_out += s_vnums
            elif (gou_cnt2 == 4):
                s_v = List_s4[s_hv * 16 + s_lv]
                s_vnum = bin(s_v)
                s_vnum = s_vnum.replace("0b", "")
                if len(s_vnum) < 4:
                    s_vnums = "0" * (4 - len(s_vnum))
                    s_vnums += s_vnum
                else:
                    s_vnums = s_vnum
                s_out += s_vnums
            elif (gou_cnt2 == 5):
                s_v = List_s5[s_hv * 16 + s_lv]
                s_vnum = bin(s_v)
                s_vnum = s_vnum.replace("0b", "")
                if len(s_vnum) < 4:
                    s_vnums = "0" * (4 - len(s_vnum))
                    s_vnums += s_vnum
                else:
                    s_vnums = s_vnum
                s_out += s_vnums
            elif (gou_cnt2 == 6):
                s_v = List_s6[s_hv * 16 + s_lv]
                s_vnum = bin(s_v)
                s_vnum = s_vnum.replace("0b", "")
                if len(s_vnum) < 4:
                    s_vnums = "0" * (4 - len(s_vnum))
                    s_vnums += s_vnum
                else:
                    s_vnums = s_vnum
                s_out += s_vnums
            elif (gou_cnt2 == 7):
                s_v = List_s7[s_hv * 16 + s_lv]
                s_vnum = bin(s_v)
                s_vnum = s_vnum.replace("0b", "")
                if len(s_vnum) < 4:
                    s_vnums = "0" * (4 - len(s_vnum))
                    s_vnums += s_vnum
                else:
                    s_vnums = s_vnum
                s_out += s_vnums
            elif (gou_cnt2 == 8):
                s_v = List_s8[s_hv * 16 + s_lv]
                s_vnum = bin(s_v)
                s_vnum = s_vnum.replace("0b", "")
                if len(s_vnum) < 4:
                    s_vnums = "0" * (4 - len(s_vnum))
                    s_vnums += s_vnum
                else:
                    s_vnums = s_vnum
                s_out += s_vnums
        s_out = to_P(s_out)
        s_outs = ""
        for i in range(0, len(s_out)):
            s_outs += s_out[i]
        l_s = l[cnt_r - 1]
        r[cnt_r] = ""
        for i in range(0, len(l_s)):
            r[cnt_r] += str(int(s_outs[i]) ^ int(l_s[i]))
        cnt_r += 1
    secret = ""
    secret = r[16] + l[16]
    secret_s = IPS(secret)
    secret_ss = ""
    for i in range(0, len(secret_s)):
        secret_ss += str(secret_s[i])

    print(secret_ss)

    i_tobase = 0
    secret_tobase = ""
    ans_ss=""
    while i_tobase < len(secret_ss):
        group_tobase = secret_ss[i_tobase:i_tobase + 8]
        i_tobase += 8
        p = 1
        ans = 0
        for x in range(len(group_tobase) - 1, -1, -1):
            ans += (ord(group_tobase[x]) - ord('0')) * p
            p *= 2
        ans_s=chr(ans)
        ans_ss+=ans_s
    print(ans_ss)
    #print(secret_tobase)

调试数据

在第一次编写DES算法时,遇到了不少困难。。苦于网上不好找到现成的参考资料,于是我为大家生成了一组加密算法各个步骤当中的中间结果,方便大家单步调试(包括16轮子密钥,每一轮左右输出,E盒扩展结果、异或后的结果、s盒的输出。。。。)。
加密输入:
明文:computer
密钥:01234567

k1:010100000010110010101100010101000010001101000111
E盒子:1000000000010111111111101000000011010100000001101轮异或:110100000011101101010010110101001111011101000001
l1:00000000111111110000011010000011
r1:11111111011100000001111101001100
k2:010100001010110010100100011101001000000101000101
E盒子:0111111111101011101000000000111111101010010110012轮异或:001011110100011100000100011110110110101100011100
l2:11111111011100000001111101001100
r2:00111011100001110001000011110111
k3:110100001010110000100110010000101010010011001110
E盒子:1001111101111100000011101000101000010111101011103轮异或:010011111101000000101000110010001011001101100000
l3:00111011100001110001000011110111
r3:10001100011110101000010000110000
k4:111000001010011000100110011011001011010110001001
E盒子:0100010110000011111101010100000010000001101000014轮异或:101001010010010111010011001011000011010000101000
l4:10001100011110101000010000110000
r4:11000001111000101110110101101011
k5:111000001001011000100110001010100101010001101011
E盒子:1110000000111111000001010111010110101011010101115轮异或:000000001010100100100011010111111111111100111100
l5:11000001111000101110110101101011
r5:01011111101100110111111011011001
k6:111000001001001001110010010011101101100100100010
E盒子:1010111111111101101001101011111111010110111100106轮异或:010011110110111111010100111100010000111111010000
l6:01011111101100110111111011011001
r6:10001001111100010110111000111010
k7:101001001101001001110010100001000100110101111000
E盒子:0100010100111111101000101011010111000001111101017轮异或:111000011110110111010000001100011000110010001101
l7:10001001111100010110111000111010
r7:10101000100010010111000001110110
k8:101001100101001101010010110010011001101001010000
E盒子:0101010100010100010100101011101000000011101011018轮异或:111100110100011100000000011100111001100111111101
l8:10101000100010010111000001110110
r8:00001000100111111111111010000101
k9:001001100101001101010011110010011000001001111000
E盒子:1000010100010100111111111111111111010100000010109轮异或:101000110100011110101100001101100101011001110010
l9:00001000100111111111111010000101
r9:00001001011001111110010101000100
k10:001011110101000101010001100100011101111000001100
E盒子:00000101001010110000111111110000101010100000100010轮异或:001010100111101001011110011000010111010000000100
l10:00001001011001111110010101000100
r10:10110011011110100010100011001011
k11:000011110100000111011001000110000001011010110100
E盒子:11011010011010111111010000010101000101100101011111轮异或:110101010010101000101101000011010000000011100011
l11:10110011011110100010100011001011
r11:11101000011001111011111010010110
k12:000111110100000110011001100110010110100010100101
E盒子:01110101000000110000111111011111110101001010110112轮异或:011010100100001010010110010001101011110000001000
l12:11101000011001111011111010010110
r12:01010111111111000101110011110100
k13:000111110000100110001001001000100110101010010001
E盒子:00101010111111111111100000101111100101111010100013轮异或:001101011111011001110001000011011111110100111001
l13:01010111111111000101110011110100
r13:01011001111101000111001101000100
k14:000110110010100010001101101100110010000100010111
E盒子:00101111001111111010100000111010011010100000100014轮异或:001101000001011100100101100010010100101100011111
l14:01011001111101000111001101000100
r14:00010101010011101011100001110010
k15:000110010010110010001100101001110000001110000010
E盒子:00001010101010100101110101011111000000111010010015轮异或:000100111000011011010001111110000000000000100110
l15:00010101010011101011100001110010
r15:01001100011010001010101011001010
k16:010100010010110010001100000101110010001111000010
E盒子:00100101100000110101000101010101010101100101010016轮异或:011101001010111111011101010000100111010110010110
l16:01001100011010001010101011001010
r16:01001110000101011110111100011000
0001010001001110110101001110111100010001001011001110011000001110

DES可视化:
链接:https://pan.baidu.com/s/1SkjSNqCYg1Xs2udSCs0I9g
提取码:yyds

好的,我来解答你的问题。 首先,DES是一种对称加密算法,可以使用Python中的`pycryptodome`库来进行实现。安装`pycryptodome`库的命令是: ``` pip install pycryptodome ``` 然后,我们需要先生成一个随机的密钥,代码如下: ```python from Crypto.Cipher import DES import os def generate_key(): return os.urandom(8) # 生成8字节的随机密钥 ``` 接下来,我们需要实现文件加密和解密的函数,代码如下: ```python def encrypt_file(key, input_file_path, output_file_path): des_cipher = DES.new(key, DES.MODE_ECB) # 使用ECB模式进行加密 with open(input_file_path, "rb") as input_file: with open(output_file_path, "wb") as output_file: while True: chunk = input_file.read(8) # 每次读取8字节 if len(chunk) == 0: break elif len(chunk) % 8 != 0: chunk += b" " * (8 - len(chunk) % 8) # 补全至8字节 output_file.write(des_cipher.encrypt(chunk)) # 加密并写入输出文件 def decrypt_file(key, input_file_path, output_file_path): des_cipher = DES.new(key, DES.MODE_ECB) # 使用ECB模式进行解密 with open(input_file_path, "rb") as input_file: with open(output_file_path, "wb") as output_file: while True: chunk = input_file.read(8) # 每次读取8字节 if len(chunk) == 0: break output_file.write(des_cipher.decrypt(chunk)) # 解密并写入输出文件 ``` 最后,我们可以使用`tkinter`库来实现可视化界面。代码如下: ```python import tkinter as tk from tkinter import filedialog class App: def __init__(self, master): self.master = master self.master.title("DES文件加密器") self.master.geometry("300x150") self.key_label = tk.Label(self.master, text="密钥:") self.key_label.pack() self.key_entry = tk.Entry(self.master, show="*") self.key_entry.pack() self.input_file_label = tk.Label(self.master, text="输入文件:") self.input_file_label.pack() self.input_file_entry = tk.Entry(self.master) self.input_file_entry.pack() self.input_file_button = tk.Button(self.master, text="选择文件", command=self.select_input_file) self.input_file_button.pack() self.output_file_label = tk.Label(self.master, text="输出文件:") self.output_file_label.pack() self.output_file_entry = tk.Entry(self.master) self.output_file_entry.pack() self.output_file_button = tk.Button(self.master, text="选择文件", command=self.select_output_file) self.output_file_button.pack() self.encrypt_button = tk.Button(self.master, text="加密", command=self.encrypt_file) self.encrypt_button.pack() self.decrypt_button = tk.Button(self.master, text="解密", command=self.decrypt_file) self.decrypt_button.pack() self.quit_button = tk.Button(self.master, text="退出", command=self.master.quit) self.quit_button.pack() def select_input_file(self): file_path = filedialog.askopenfilename() self.input_file_entry.delete(0, tk.END) self.input_file_entry.insert(0, file_path) def select_output_file(self): file_path = filedialog.asksaveasfilename() self.output_file_entry.delete(0, tk.END) self.output_file_entry.insert(0, file_path) def get_key(self): key = self.key_entry.get() if len(key) != 8: tk.messagebox.showwarning("警告", "密钥长度不为8") return None return key.encode() def get_input_file_path(self): return self.input_file_entry.get() def get_output_file_path(self): return self.output_file_entry.get() def encrypt_file(self): key = self.get_key() if key is None: return input_file_path = self.get_input_file_path() output_file_path = self.get_output_file_path() if input_file_path == "" or output_file_path == "": tk.messagebox.showwarning("警告", "请选择输入文件和输出文件") return encrypt_file(key, input_file_path, output_file_path) tk.messagebox.showinfo("提示", "加密完成") def decrypt_file(self): key = self.get_key() if key is None: return input_file_path = self.get_input_file_path() output_file_path = self.get_output_file_path() if input_file_path == "" or output_file_path == "": tk.messagebox.showwarning("警告", "请选择输入文件和输出文件") return decrypt_file(key, input_file_path, output_file_path) tk.messagebox.showinfo("提示", "解密完成") root = tk.Tk() app = App(root) root.mainloop() ``` 这样就实现了一个简单的DES文件加密器,并且具有可视化界面
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值