前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >DES算法的python实现

DES算法的python实现

作者头像
十二惊惶
发布2024-02-28 20:14:49
640
发布2024-02-28 20:14:49
举报

先上代码吧:

代码语言:javascript
复制
import re
def my_read(filename,row,col):
    # 读取各种矩阵----参数为文件名和目标矩阵的行列数
    sz = [[0 for i in range(col)]for i in range(row)]
    with open(filename,"r") as s1:
        lists = s1.readlines()
        for i in range(len(sz)):
            lists[i] = lists[i].split(',')
            # 以 , 将字符串分开
            for j in range(len(sz[0])):
                sz[i][j] = lists[i][j]
    return sz
    # 返回一个该矩阵的二维数组

def ord_bin(str1):
    str1_hex = ''
    for i in str1:
        str1_hex = str1_hex + bin(ord(i))[:1] + bin(ord(i))[2:]
    return str1_hex

def create_L0R0():
    #生成L0,R0
    mingwen= [[0 for i in range(8)]for i in range(8)]
    MW="abcdefgh"
    str1_hex=ord_bin(MW)
    for i in range (8):
        for j in range(8):
            mingwen[i][j]=str1_hex[i*8+j]
    rep = my_read("IP.txt",8,8)
    #读取置换矩阵
    rep_mingwen = replace(mingwen,rep,8,8)
    #进行初始置换
    L0 = []
    R0 = []
    for i in range(4):
        #得到c0
        for j in range(8):
            x,y = get_xy(int(rep[i][j]),8,8)
            #检查坐标
            L0.extend(rep_mingwen[x][y])
    for i in range(4,8):
        #得到d0
        for j in range(8):
            x,y = get_xy(int(rep[i][j]),8,8)
            #检查坐标
            R0.extend(rep_mingwen[x][y])
    return [L0,R0]


def get_xy(n,row,col):
    # n为要转化为坐标的数值
    if n % col == 0:
        x = int(n/col) -1
        y = col - 1
    else:
        x = int(n/col)
        y = n%col - 1
    return [x,y]

def replace(temp,rep,row,col):
    # 定义一个置换函数,参数temp为要替换的矩阵,file为替换矩阵,row列,col行
    new_temp = [[0 for i in range(col)]for i in range(row)]
    # 用来保存置换后的矩阵并作为返回值
    for i in range(len(temp)):
        for j in range(len(temp[0])):
            x,y = get_xy(int(rep[i][j]),row,col)
            if int(rep[i][j])%8 == 0:
                new_temp[i][j] = temp[x-1][7]
                # print(temp[x-1][7],end = ' ')
            else:
                new_temp[i][j] = temp[x][y]
    return new_temp[:]


def child_key():
    # 生成k1~k16的子密钥
    key = [[0 for i in range(8)] for i in range(8)]
    KEY = "abcdefgh"
    str1_hex = ord_bin(KEY)
    for i in range(8):
        for j in range(8):
            key[i][j] = str1_hex[i * 8 + j]
    # 读取64位key
    c = []
    d = []
    k = []
    c0,d0 = create_L0R0()
    # 得到c0,d0
    num = [1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1]
    # 设置第n次循环左移位数
    for i in range(16):
        # 将生成k1~k16的子密钥存放在列表k中
        c0 = my_move(c0,num[i])
        d0 = my_move(d0,num[i])
        k1 = []
        k1.extend(c0)
        k1.extend(d0)
        pc_2 = my_read("PC-2.txt",8,6)
        temp = []
        # 暂时存放56位子密钥
        for m in range(8):
            for n in range(6):
                temp.append(k1[int(pc_2[m][n])-1])
        k.append(temp)
    return k[:]

    # k位16x48的子密钥二维数组


def my_move(list,n):
    #循环移位,n为移位数
    for i in range(n):##左移
        list.insert(len(list),list[0])
        list.remove(list[0])
    return list


def E_extend(R0):
    #将32位Ri扩展位48位
    Ri = []
    e = my_read("E_extend.txt",8,6)
    for m in range(len(e)):
        for n in range(len(e[0])):
            Ri.append(R0[int(e[m][n])-1])
    #print(Ri)
    return Ri


def yihuo(a,c):
    #进行异或运算
    B = []
    for n in range(len(a)):
        b = []
        if int(a[n]) == int(c[n]):
            b.append(0)
        else:
            b.append(1)
        B.extend(b)
    return  B


def create_B(K,ERi,num):
    #进行异或运算,K为48位子密钥列表,ERi为48位扩展的Ri,num是轮数
    B = []
    for m in range(len(K)):
        b = []
        for n in range(len(K[0])):
            if K[m][n] == ERi[n]:
                b.append(0)
            else:
                b.append(1)
        B.append(b)
    return  B[num]
    #返回值为B0~B7的集合列表B


def get_bi(B):
    b0 = ''
    b1 = ''
    b2 = ''
    b3 = ''
    b4 = ''
    b5 = ''
    b6 = ''
    b7 = ''
    for i in range(6):
        b0 = b0 + str(B[i])
    for i in range(6,12):
        b1 = b1 + str(B[i])
    for i in range(12,18):
        b2 = b2 + str(B[i])
    for i in range(18,24):
        b3 = b3 + str(B[i])
    for i in range(24,30):
        b4 = b4 + str(B[i])
    for i in range(30,36):
        b5 = b5 + str(B[i])
    for i in range(36,42):
        b6 = b6 + str(B[i])
    for i in range(42,48):
        b7 = b7 + str(B[i])
    return [b0,b1,b2,b3,b4,b5,b6,b7]

def get_lastR(K,R0,num):
    #num为轮数
    ERi = E_extend(R0)
    #E扩展
    B = create_B(K,ERi,num)
    #num轮数用来控制Ki
    b0,b1,b2,b3,b4,b5,b6,b7 = get_bi(B)
    b0 = cut_bi(b0,0)
    b1 = cut_bi(b1,1)
    b2 = cut_bi(b2,2)
    b3 = cut_bi(b3,3)
    b4 = cut_bi(b4,4)
    b5 = cut_bi(b5,5)
    b6 = cut_bi(b6,6)
    b7 = cut_bi(b7,7)
    last_R = []
    last_R.extend(b0)
    last_R.extend(b1)
    last_R.extend(b2)
    last_R.extend(b3)
    last_R.extend(b4)
    last_R.extend(b5)
    last_R.extend(b6)
    last_R.extend(b7)
    return last_R


def read_s(num):
    if num+1 == 1:
        s = my_read("S_box1.txt",4,16)
    elif num+1 == 2:
        s = my_read("S_box2.txt",4,16)
    elif num+1 == 3:
        s = my_read("S_box3.txt",4,16)
    elif num+1 == 4:
        s = my_read("S_box4.txt",4,16)
    elif num+1 == 5:
        s = my_read("S_box5.txt",4,16)
    elif num+1 == 6:
        s = my_read("S_box6.txt",4,16)
    elif num+1 == 7:
        s = my_read("S_box7.txt",4,16)
    else:
        s = my_read("S_box8.txt",4,16)
    return s

def cut_bi(b,n):
    x = my_int2(b[0],b[5])
    y = my_int4(b[1],b[2],b[3],b[4])
    s = read_s(n+1)
    s =[]
    temp = read_s(n)
    s.append(my_bin(int(temp[x][y])))
    return s

def my_int2(a1,a2):
    a = a1 + a2
    if a == '00':
        a = int(0)
    elif a == '01':
        a = int(1)
    elif a == '10':
        a = int(2)
    else:
        a = int(3)
    return a


def my_int4(a1,a2,a3,a4):
    a = a1 + a2 + a3 + a4
    if a == '0000':
        a = int(0)
    elif a == '0001':
        a = int(1)
    elif a == '0010':
        a = int(2)
    elif a == '0011':
        a = int(3)
    elif a == '0100':
        a = int(4)
    elif a == '0101':
        a = int(5)
    elif a == '0110':
        a = int(6)
    elif a == '0111':
        a = int(7)
    elif a == '1000':
        a = int(8)
    elif a == '1001':
        a = int(9)
    elif a == '1010':
        a = int(10)
    elif a == '1011':
        a = int(11)
    elif a == '1100':
        a = int(12)
    elif a == '1101':
        a = int(13)
    elif a == '1110':
        a = int(14)
    else:
        a = int(15)
    return a

def my_bin(a):
    if a == 0:
        a = '0000'
    elif a == 1:
        a = '0001'
    elif a == 2:
        a = '0010'
    elif a == 3:
        a = '0011'
    elif a == 4:
        a = '0100'
    elif a == 5:
        a = '0101'
    elif a == 6:
        a = '0110'
    elif a == 7:
        a = '0111'
    elif a == 8:
      a = '1000'
    elif a == 9:
        a = '1001'
    elif a == 10:
        a = '1010'
    elif a == 11:
        a = '1011'
    elif a == 12:
        a = '1100'
    elif a == 13:
        a = '1101'
    elif a == 14:
        a = '1110'
    else:
        a = '1111'
    return a

def change(temp):
    list = []
    for m in range(len(temp)):
        for n in range(len(temp[0])):
            list.append(temp[m][n])
    return list


K = child_key()
#获取k1~k16的子密钥存依次放在列表K中
L0,R0 = create_L0R0()
#获取L0,R0
for num in range(16):
    #16轮循环
    L = R0
    temp = get_lastR(K,R0,num)
    temp = change(temp)
    #改变一下格式,使temp和L0格式一样,方便实现异或运算
    R = yihuo(L0,temp)
    L0 = L
    R0 = R
mw = []
#存放最终的L,R
mw.extend(L)
mw.extend(R)
rep = my_read("IP-1.txt",8,8)
#进行最后一步逆置换并输出密文
miwen = []
linshi = ''
new_miwen=''
new_miwen2=''
for m in range(len(rep)):
    for n in range(len(rep[0])):
        linshi=linshi+str(mw[int(rep[m][n])-1])
print(linshi)
new_miwen = re.findall(r'.{8}', linshi)
str_1 = ""
for b in new_miwen:
    str_1 += chr(int(b, 2))
print(str_1)

最后的结果实际上也是存在一些问题,在个人后面的验证中也没有找清楚问题出在了哪里?但是大致思路应该没问题

文件读写操作:

代码语言:javascript
复制
def my_read(filename,row,col):
    # 读取各种矩阵----参数为文件名和目标矩阵的行列数
    sz = [[0 for i in range(col)]for i in range(row)]
    with open(filename,"r") as s1:
        lists = s1.readlines()
        for i in range(len(sz)):
            lists[i] = lists[i].split(',')
            # 以 , 将字符串分开
            for j in range(len(sz[0])):
                sz[i][j] = lists[i][j]
    return sz
    # 返回一个该矩阵的二维数组
本文参与?腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2022-04-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客?前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与?腾讯云自媒体分享计划? ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 文件读写操作:
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
http://www.vxiaotou.com