DES算法的python3实现
DES原理
DES原理 这里不予以复述, 有很多优秀的博客
原理可以参考这篇博客
https://www.cnblogs.com/songwenlong/p/5944139.html
DES实现
1. 主函数框架
DES 函数 传入参数为
- text(明文 或者 密文)
- key (解密的key)
- flag (是加密还是解密过程)
# DES 算法实现 flag是标志位 当为-1时, 是DES解密, flag默认为0
def DES (text, key, flag = "0"):
# 初始字段
# IP置换
InitKeyCode = IP(text)
# 产生子密钥 集合
subkeylist = createSubkey(key)
# 获得Ln 和 Rn
Ln = InitKeyCode[0:32]
Rn = InitKeyCode[32:]
# 如果是解密的过程 把子密钥数字逆过来 就变成解密过程了
if (flag == "-1") :
subkeylist = subkeylist[::-1]
for subkey in subkeylist:
while len(Rn) < 32:
Rn = "0" + Rn
while len(Ln) < 32:
Ln = "0" + Ln
# 对右边进行E-扩展
Rn_expand = E_expend(Rn)
# 压缩后的密钥与扩展分组异或以后得到48位的数据,将这个数据送入S盒
S_Input = int(Rn_expand, base=2) ^ int(subkey, base=2)
# 进行S盒替代
S_sub_str = S_sub(S_Input)
#P盒置换 并且
# 左、右半部分交换,接着开始另一轮
(Ln, Rn) = P(Ln, S_sub_str, Rn)
#进行下一轮轮置换
# 最后一轮之后 左、右两半部分并未进行交换
# 而是两部分合并形成一个分组做为末置换的输入。
# 所以要重新置换 一次
(Ln, Rn) = (Rn, Ln)
# 末置换得到密文
re_text = IP_inverse(Ln, Rn)
return re_text
2. 各种置换矩阵的定义
DES有各种置换矩阵的定义, 所以提前定义好, 但是这里虽然说是矩阵 但是使用数组来表示的
# S盒 的置换矩阵
S_MATRIX = [(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)]
# P置换的置换矩阵
P_MATRIX = [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]
# IP置换的 置换矩阵
IP_MATRIX = [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]
# 压缩置换矩阵 从56位里选48位
COMPRESS_MATRIXS = [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扩展置换矩阵
E_MATRIX = [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]
# IP逆置换矩阵
IP_INVERSE_MATRIX = [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]
3.IP置换函数
对于置换 我们的明文是用一个长度为64的字符01串构成的 所以置换 只需要新的字符串 然后按照置换矩阵的下表来把原字符串的单个字符加入
def IP(Mingwen):
#如果长度不是64 就退出
assert len(Mingwen) == 64
ret = ""
#通过循环 进行IP置换
for i in IP_MATRIX:
ret = ret + Mingwen[i - 1]
return ret
4. 循环左移位数函数
对输入的str 按照shift_count的大小 左移shift_count位 这个函数主要用于子密钥生成
def shift(str, shift_count):
try:
if len(str) > 28:
raise NameError
except TypeError:
pass
str = str[shift_count:] + str[0:shift_count]
return str
5.生成子密钥函数
此函数用来生成子密钥 生成16组子密钥 用于和扩展分组 异或
def createSubkey(key):
# 如果key长度不是64 就退出
assert len(key) == 64
#DES的密钥由64位减至56位,每个字节的第8位作为奇偶校验位
#把56位 变成 2个28位
Llist = [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]
Rlist = [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]
# 初试生成 左右两组28位密钥
L0 = ""
R0 = ""
for i in Llist:
L0 += key[i - 1]
for i in Rlist:
R0 += key[i - 1]
assert len(L0) == 28
assert len(R0) == 28
#轮函数生成 48位密钥
#定义轮数
Movetimes = [1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1]
#定义返回的subKey
retkey = []
#开始轮置换
for i in range(0, 16):
#获取左半边 和 右半边 shift函数用来左移生成轮数
L0 = shift(L0, Movetimes[i])
R0 = shift(R0, Movetimes[i])
#合并左右部分
mergedKey = L0 + R0
tempkey = ""
# 压缩置换矩阵 从56位里选48位
#选出48位子密钥
for i in COMPRESS_MATRIXS:
tempkey += mergedKey[i - 1]
assert len(tempkey) == 48
#加入生成子密钥
retkey.append(tempkey)
return retkey
6.E扩展置换
用于把右边的32位扩展成48位
def E_expend(Rn):
retRn = ""
for i in E_MATRIX:
retRn += Rn[i - 1]
assert len(retRn) == 48
return retRn
7.S盒替换函数
压缩后的密钥与扩展分组异或以后得到48位的数据,将这个数据送入S盒,进行替代运算。替代由8个不同的S盒完成,每个S盒有6位输入4位输出。48位输入分为8个6位的分组,一个分组对应一个S盒,对应的S盒对各组进行代替操作。
# S盒替代运算
def S_sub(S_Input):
#从第二位开始的子串 去掉0X
S_Input = bin(S_Input)[2:]
while len(S_Input) < 48:
S_Input = "0" + S_Input
index = 0
retstr = ""
for Slist in S_MATRIX:
# 输入的高低两位做为行数row
row = int(S_Input[index] + S_Input[index + 5], base=2)
# 中间四位做为列数L
col = int(S_Input[index + 1:index + 5], base=2)
# 得到 result的 单个四位输出
ret_single = bin(Slist[row * 16 + col])[2:]
while len(ret_single) < 4:
ret_single = "0" + ret_single
# 合并单个输出
retstr += ret_single
# index + 6 进入下一个六位输入
index += 6
assert len(retstr) == 32
return retstr
8.P置换
S盒代替运算的32位输出按照P盒进行置换
最后,P盒置换的结果与最初的64位分组左半部分L0异或,然后左、右半部分交换,接着开始另一轮。
def P(Ln, S_sub_str, oldRn):
# P 盒置换
tmp = ""
for i in P_MATRIX:
tmp += S_sub_str[i - 1]
# P盒置换的结果与最初的64位分组左半部分L0异或
LnNew = int(tmp, base=2) ^ int(Ln, base=2)
LnNew = bin(LnNew)[2:]
while len(LnNew) < 32:
LnNew = "0" + LnNew
assert len(LnNew) == 32
# 左、右半部分交换,接着开始另一轮
(Ln, Rn) = (oldRn, LnNew)
return (Ln, Rn)
9. IP逆置换
末置换是初始置换的逆过程,DES最后一轮后,左、右两半部分并未进行交换,而是两部分合并形成一个分组做为末置换的输入
置换后得到密文或者解密的明文
def IP_inverse(L16, R16):
tmp = L16 + R16
retstr = ""
for i in IP_INVERSE_MATRIX:
retstr += tmp[i - 1]
assert len(retstr) == 64
return retstr
10. TEST函数
用来测试效果
if __name__ == "__main__":
key = "0101101000110101010101110111100110010011001100110100111101100111"
Mingwen = "1001101010110101011001110011001001010001010101110011010110110011"
#打印明文的16进制形式
print("明文的16进制形式: " + hex(int(Mingwen, base=2)).upper())
ciphertext = DES(Mingwen, key)
#打印加密后的密文
print("加密后的密文: " + hex(int(ciphertext, base=2)).upper())
falseKey = "0001101000110101010101110111100110010011001100110100111101100111"
decode_ciphertext = DES(ciphertext, key, "-1")
#打印解密后的明文 看是否相同
print("解密后的明文: " + hex(int(decode_ciphertext, base=2)).upper())
decode_ciphertext = DES(ciphertext, falseKey, "-1")
# 打印给定错误的key 解密后的明文 看是否不同
print("给定错误的key 解密后的明文:" + hex(int(decode_ciphertext, base=2)).upper())
实现结果

代码传送门
DES算法的python3实现的更多相关文章
- DES算法详解
本文主要介绍了DES算法的步骤,包括IP置换.密钥置换.E扩展置换.S盒代替.P盒置换和末置换. 1.DES算法简介 DES算法为密码体制中的对称密码体制,又被称为美国数据加密标准. DES是一个分组 ...
- 基于DES算法加密的防撞库密码系统项目总结
项目内容:基于DES算法加密的防撞库密码系统 小组名:zqhzkzkj 目标:1.对用户输入的8位字符进行DES加密,要求用户输入8位密钥 2.对于不同的网站,不同的用户名生成不同的密码 小组成员:周 ...
- DES 算法的 C++ 与 JAVA 互相加解密
国内私募机构九鼎控股打造APP,来就送 20元现金领取地址:http://jdb.jiudingcapital.com/phone.html内部邀请码:C8E245J (不写邀请码,没有现金送)国内私 ...
- MFC 简单实现 DES 算法
前言 徐旭东老师说过学者就应该对知识抱有敬畏之心,所以我的博客的标题总喜欢加上"简单"二字,就是为了提醒自己,自己所学知识只是皮毛,离真理还远矣. DES 算法 DES算法是密码体 ...
- 在IOS中使用DES算法对Sqlite数据库进行内容加密存储并读取解密
在IOS中使用DES算法对Sqlite 数据库进行内容加密存储并读取解密 涉及知识点: 1.DES加密算法: 2.OC对Sqlite数据库的读写: 3.IOS APP文件存储的两种方式及读取方式. 以 ...
- Asp.Net 常用工具类之加密——对称加密DES算法(2)
又到周末,下午博客园看了两篇文章,关于老跳和老赵的程序员生涯,不禁感叹漫漫程序路,何去何从兮! 转眼毕业的第三个年头,去过苏州,跑过上海,从一开始的凌云壮志,去年背起行囊默默回到了长沙准备买房,也想有 ...
- AES算法,DES算法,RSA算法JAVA实现
1 AES算法 1.1 算法描述 1.1.1 设计思想 Rijndael密码的设计力求满足以下3条标准: ① 抵抗所有已知的攻击. ② 在多个平台上速度快,编码紧凑. ③ 设计 ...
- 安全体系(一)—— DES算法详解
本文主要介绍了DES算法的步骤,包括IP置换.密钥置换.E扩展置换.S盒代替.P盒置换和末置换. 安全体系(零)—— 加解密算法.消息摘要.消息认证技术.数字签名与公钥证书 安全体系(二)——RSA算 ...
- DES算法原理完整版
1.所需参数 key:8个字节共64位的工作密钥 data:8个字节共64位的需要被加密或被解密的数据 mode:DES工作方式,加密或者解密 2.初始置换 DES算法使用64位的密钥key将64位的 ...
随机推荐
- java 之 实例方法和类方法
类方法:使用static修饰(静态方法),属于整个类的,不是属于某个实例的,只能处理static域或调用static方法: 实例方法:属于对象的方法,由对象来调用. 判断类方法,类方法的前面有stat ...
- 轻松应对并发问题,简易的火车票售票系统,Newbe.Claptrap 框架用例,第一步 —— 业务分析
Newbe.Claptrap 框架非常适合于解决具有并发问题的业务系统.火车票售票系统,就是一个非常典型的场景用例. 本系列我们将逐步从业务.代码.测试和部署多方面来介绍,如何使用 Newbe.Cla ...
- abp vnext 开发快速入门 1 认识框架
最近在做一个项目,用的框架是Abp vnext ,不是Abp, 我自己也是刚开始用这个框架来做项目,难免要查资料,这个框架官方有中文文档,可以到官网www.abp.io 去查看,国内也有一些写了相关的 ...
- 分布式 ID 解决方案之美团 Leaf
分布式 ID 在庞大复杂的分布式系统中,通常需要对海量数据进行唯一标识,随着数据日渐增长,对数据分库分表以后需要有一个唯一 ID 来标识一条数据,而数据库的自增 ID 显然不能满足需求,此时就需要有一 ...
- Winform开发中的困境及解决方案
在我们开发各种应用的时候,都会碰到很多不同的问题,这些问题涉及架构.模块组合.界面处理.共同部分抽象等方面,我们这里以Winform开发为例,从系统模块化.界面组件选择.业务模块场景划分.界面基类和辅 ...
- pandas处理excel文件和csv文件
一.csv文件 csv以纯文本形式存储表格数据 pd.read_csv('文件名'),可添加参数engine='python',encoding='gbk' 一般来说,windows系统的默认编码为g ...
- Java中包装类Test类测试出错的解决方法(JUnit5)
import org.junit.jupiter.api.Test; public class TestJunit { public static void main(String[]args) { ...
- Day18_下单
学于黑马和传智播客联合做的教学项目 感谢 黑马官网 传智播客官网 微信搜索"艺术行者",关注并回复关键词"乐优商城"获取视频和教程资料! b站在线视频 0.学习 ...
- Python字符串更新
Python字符串更新:截取字符串的某一部分 和 其他字符串进行拼接. 注:可以修改字符串的值,但修改的不是内存中的值,而是创建新的字符串. 1.使用字符串常量进行更新: # 使用字符串常量 strs ...
- Python获取当前时间_获取格式化时间_格式化日期
Python获取当前时间_获取格式化时间: Python获取当前时间: 使用 time.time( ) 获取到距离1970年1月1日的秒数(浮点数),然后传递给 localtime 获取当前时间 #使 ...