DES算法的python实现

2024-02-28 20:14:49 浏览数 (2)

先上代码吧:

代码语言: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
    # 返回一个该矩阵的二维数组

0 人点赞