python实现DES加密解密方法实例详解


Posted in Python onJune 30, 2015

本文实例讲述了python实现DES加密解密方法。分享给大家供大家参考。具体分析如下:

实现功能:加密中文等字符串
密钥与明文可以不等长
这里只贴代码,加密过程可以自己百度,此处python代码没有优化

1. desstruct.py DES加密中要使用的结构体

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)
ip_1=(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)
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)
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)
s=[ [[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]]]
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, 33, 15,
  7, 62, 54, 46, 38, 30, 22,
  14, 6, 61, 53, 45, 37, 29,
  21, 13, 5, 28, 20, 12, 4);
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)
d = ( 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1)

2. des.py 加密文件

#_*_ coding:utf-8 _*_
#!/usr/bin/env python
#Filename:des.py
from desstruct import *
import re
__all__=['desencode']
class DES():
 '''des 加密'''
 def __init__(self):
  pass
 #加密
 def code(self,from_code,key,code_len,key_len):
  output=""
  trun_len=0
  #将密文和密钥转换为二进制
  code_string=self._functionCharToA(from_code,code_len)
  code_key=self._functionCharToA(key,key_len)
  #如果密钥长度不是16的整数倍则以增加0的方式变为16的整数倍
  if code_len%16!=0:
   real_len=(code_len/16)*16+16
  else:
   real_len=code_len
  if key_len%16!=0:
   key_len=(key_len/16)*16+16
  key_len*=4
  #每个16进制占4位
  trun_len=4*real_len
  #对每64位进行一次加密
  for i in range(0,trun_len,64):
   run_code=code_string[i:i+64]
   l=i%key_len
   run_key=code_key[l:l+64]
   #64位明文、密钥初始置换
   run_code= self._codefirstchange(run_code)
   run_key= self._keyfirstchange(run_key)
   #16次迭代
   for j in range(16):
    #取出明文左右32位
    code_r=run_code[32:64]
    code_l=run_code[0:32]
    #64左右交换
    run_code=code_r
    #右边32位扩展置换
    code_r= self._functionE(code_r)
    #获取本轮子密钥
    key_l=run_key[0:28]
    key_r=run_key[28:56]
    key_l=key_l[d[j]:28]+key_l[0:d[j]]
    key_r=key_r[d[j]:28]+key_r[0:d[j]]
    run_key=key_l+key_r
    key_y= self._functionKeySecondChange(run_key)
    #异或
    code_r= self._codeyihuo(code_r,key_y)
    #S盒代替/选择
    code_r= self._functionS(code_r)
    #P转换
    code_r= self._functionP(code_r)
    #异或
    code_r= self._codeyihuo(code_l,code_r)
    run_code+=code_r
   #32互换
   code_r=run_code[32:64]
   code_l=run_code[0:32]
   run_code=code_r+code_l
   #将二进制转换为16进制、逆初始置换
   output+=self._functionCodeChange(run_code)
  return output
 #异或 
 def _codeyihuo(self,code,key):
  code_len=len(key)
  return_list=''
  for i in range(code_len):
   if code[i]==key[i]:
    return_list+='0'
   else:
    return_list+='1'
  return return_list
 #密文或明文初始置换
 def _codefirstchange(self,code):
  changed_code=''
  for i in range(64):
   changed_code+=code[ip[i]-1]
  return changed_code
 #密钥初始置换
 def _keyfirstchange (self,key):
  changed_key=''
  for i in range(56):
   changed_key+=key[pc1[i]-1]
  return changed_key
 #逆初始置换
 def _functionCodeChange(self, code):
  lens=len(code)/4
  return_list=''
  for i in range(lens):
   list=''
   for j in range(4):
    list+=code[ip_1[i*4+j]-1]
   return_list+="%x" %int(list,2)
  return return_list
 #扩展置换 
 def _functionE(self,code):
  return_list=''
  for i in range(48):
   return_list+=code[e[i]-1]
  return return_list  
 #置换P  
 def _functionP(self,code):
  return_list=''
  for i in range(32):
   return_list+=code[p[i]-1]
  return return_list
 #S盒代替选择置换
 def _functionS(self, key):
  return_list=''
  for i in range(8):
   row=int( str(key[i*6])+str(key[i*6+5]),2)
   raw=int(str( key[i*6+1])+str(key[i*6+2])+str(key[i*6+3])+str(key[i*6+4]),2)
   return_list+=self._functionTos(s[i][row][raw],4)
  return return_list
 #密钥置换选择2
 def _functionKeySecondChange(self,key):
  return_list=''
  for i in range(48):
   return_list+=key[pc2[i]-1]
  return return_list
 #将十六进制转换为二进制字符串
 def _functionCharToA(self,code,lens):
  return_code=''
  lens=lens%16
  for key in code:
   code_ord=int(key,16)
   return_code+=self._functionTos(code_ord,4)  
  if lens!=0:
   return_code+='0'*(16-lens)*4
  return return_code
 #二进制转换
 def _functionTos(self,o,lens):
  return_code=''
  for i in range(lens):
   return_code=str(o>>i &1)+return_code
  return return_code
#将unicode字符转换为16进制
def tohex(string):
 return_string=''
 for i in string:
  return_string+="%02x"%ord(i)
 return return_string
def tounicode(string):
 return_string=''
 string_len=len(string)
 for i in range(0,string_len,2):
  return_string+=chr(int(string[i:i+2],16))
 return return_string
#入口函数
def desencode(from_code,key):
 #转换为16进制
 from_code=tohex(from_code)
 key=tohex(key)
 des=DES()
 key_len=len(key)
 string_len=len(from_code)  
 if string_len<1 or key_len<1:
  print 'error input'
  return False
 key_code= des.code(from_code,key,string_len,key_len)
 return key_code
#测试
if __name__ == '__main__':
 print desencode('我是12345678刘就是我abcdwfd','0f1571c947刘')
#返回密文为: 84148584371a6a1fe99e1da0ce1e34649b88ed15098e8aa4b8eb0bf24885c658

3. 解密文件

#_*_coding:utf-8_*_
#!/usr/bin/env python
#Filename:des.py
from desstruct import *
import re
__all__=['desdecode']
class DES():
 '''解密函数,DES加密与解密的方法相差不大
  只是在解密的时候所用的子密钥与加密的子密钥相反
 '''
 def __init__(self):
  pass
 def decode(self,string,key,key_len,string_len):
  output=""
  trun_len=0
  num=0
  #将密文转换为二进制
  code_string=self._functionCharToA(string,string_len)
  #获取字密钥
  code_key=self._getkey(key,key_len)
  #如果密钥长度不是16的整数倍则以增加0的方式变为16的整数倍
  real_len=(key_len/16)+1 if key_len%16!=0 else key_len/16
  trun_len=string_len*4
  #对每64位进行一次加密
  for i in range(0,trun_len,64):
   run_code=code_string[i:i+64]
   run_key=code_key[num%real_len]
   #64位明文初始置换
   run_code= self._codefirstchange(run_code)
   #16次迭代
   for j in range(16):
    code_r=run_code[32:64]
    code_l=run_code[0:32]
    #64左右交换 
    run_code=code_r
    #右边32位扩展置换
    code_r= self._functionE(code_r)
    #获取本轮子密钥
    key_y=run_key[15-j]
    #异或
    code_r= self._codeyihuo(code_r,key_y)
    #S盒代替/选择
    code_r= self._functionS(code_r)
    #P转换
    code_r= self._functionP(code_r)
    #异或
    code_r= self._codeyihuo(code_l,code_r)
    run_code+=code_r
   num+=1
   #32互换
   code_r=run_code[32:64]
   code_l=run_code[0:32]
   run_code=code_r+code_l
   #将二进制转换为16进制、逆初始置换
   output+=self._functionCodeChange(run_code)
  return output
 #获取子密钥
 def _getkey(self,key,key_len):
  #将密钥转换为二进制
  code_key=self._functionCharToA(key,key_len)
  a=['']*16
  real_len=(key_len/16)*16+16 if key_len%16!=0 else key_len
  b=['']*(real_len/16)
  for i in range(real_len/16):
   b[i]=a[:]
  num=0
  trun_len=4*key_len
  for i in range(0,trun_len,64):
   run_key=code_key[i:i+64]
   run_key= self._keyfirstchange(run_key)
   for j in range(16):
    key_l=run_key[0:28]
    key_r=run_key[28:56]
    key_l=key_l[d[j]:28]+key_l[0:d[j]]
    key_r=key_r[d[j]:28]+key_r[0:d[j]]
    run_key=key_l+key_r
    key_y= self._functionKeySecondChange(run_key)
    b[num][j]=key_y[:]
   num+=1
  return b 
 #异或        
 def _codeyihuo(self,code,key):
  code_len=len(key)
  return_list=''
  for i in range(code_len):
   if code[i]==key[i]:
    return_list+='0'
   else:
    return_list+='1'
  return return_list
 #密文或明文初始置换         
 def _codefirstchange(self,code):
  changed_code=''
  for i in range(64):
   changed_code+=code[ip[i]-1]
  return changed_code
 #密钥初始置换
 def _keyfirstchange (self,key):
  changed_key=''
  for i in range(56):
   changed_key+=key[pc1[i]-1]
  return changed_key
 #逆初始置换
 def _functionCodeChange(self, code):
  return_list=''
  for i in range(16):
   list=''
   for j in range(4):
    list+=code[ip_1[i*4+j]-1]
   return_list+="%x" %int(list,2)
  return return_list
 #扩展置换 
 def _functionE(self,code):
  return_list=''
  for i in range(48):
   return_list+=code[e[i]-1]
  return return_list  
 #置换P 
 def _functionP(self,code):
  return_list=''
  for i in range(32):
   return_list+=code[p[i]-1]
  return return_list
 #S盒代替选择置换 
 def _functionS(self, key):
  return_list=''
  for i in range(8):
   row=int( str(key[i*6])+str(key[i*6+5]),2)
   raw=int(str( key[i*6+1])+str(key[i*6+2])+str(key[i*6+3])+str(key[i*6+4]),2)
   return_list+=self._functionTos(s[i][row][raw],4)
  return return_list
 #密钥置换选择2
 def _functionKeySecondChange(self,key):
  return_list=''
  for i in range(48):
   return_list+=key[pc2[i]-1]
  return return_list
 #将十六进制转换为二进制字符串
 def _functionCharToA(self,code,lens):
  return_code=''
  lens=lens%16
  for key in code:
   code_ord=int(key,16)
   return_code+=self._functionTos(code_ord,4)
  if lens!=0:
   return_code+='0'*(16-lens)*4
  return return_code
 #二进制转换
 def _functionTos(self,o,lens):
  return_code=''
  for i in range(lens):
   return_code=str(o>>i &1)+return_code
  return return_code
#将unicode字符转换为16进制
def tohex(string):
 return_string=''
 for i in string:
  return_string+="%02x"%ord(i)
 return return_string
def tounicode(string):
 return_string=''
 string_len=len(string)
 for i in range(0,string_len,2):
  return_string+=chr(int(string[i:i+2],16))
 return return_string
#入口函数
def desdecode(from_code,key):
 key=tohex(key)
 des=DES()
 key_len=len(key)
 string_len=len(from_code)
 if string_len%16!=0:
  return False
 if string_len<1 or key_len<1:
  return False
 key_code= des.decode(from_code,key,key_len,string_len)
 return tounicode(key_code)
#测试
if __name__ == '__main__':
 print desdecode('84148584371a6a1fe99e1da0ce1e34649b88ed15098e8aa4b8eb0bf24885c658','0f1571c947刘'

解密后为: 我是12345678刘就是我abcdwfd

Python DES 加密解密,就是大家所谓想要的那个非常快速的方法
这个要借助Crypto.Cipher这个插件来实现的,引用后只需要写如下代码即可

from Crypto.Cipher import DES

class MyDESCrypt:
  
  key = chr(11)+chr(11)+chr(11)+chr(11)+chr(11)+chr(11)+chr(11)+chr(11)
  iv = chr(22)+chr(22)+chr(22)+chr(22)+chr(22)+chr(22)+chr(22)+chr(22)
  
  def __init__(self,key='',iv=''):
    if len(key)> 0:
      self.key = key
    if len(iv)>0 :
      self.iv = iv
    
  def ecrypt(self,ecryptText):
    try:
      cipherX = DES.new(self.key, DES.MODE_CBC, self.iv)
      pad = 8 - len(ecryptText) % 8
      padStr = ""
      for i in range(pad):
       padStr = padStr + chr(pad)
      ecryptText = ecryptText + padStr
      x = cipherX.encrypt(ecryptText)
      return x.encode('hex_codec').upper()
    except:
      return ""
   
  
  def decrypt(self,decryptText):
    try:
      
      cipherX = DES.new(self.key, DES.MODE_CBC, self.iv)
      str = decryptText.decode('hex_codec')
      y = cipherX.decrypt(str)
      return y[0:ord(y[len(y)-1])*-1]
    except:
      return ""

建议大家可以结合一些插件使用,更方便与快捷

希望本文所述对大家的Python程序设计有所帮助。

Python 相关文章推荐
浅谈Python对内存的使用(深浅拷贝)
Jan 17 Python
python skimage 连通性区域检测方法
Jun 21 Python
Python基于SMTP协议实现发送邮件功能详解
Aug 14 Python
详解Django+Uwsgi+Nginx 实现生产环境部署
Nov 06 Python
python添加模块搜索路径和包的导入方法
Jan 19 Python
python 创建一维的0向量实例
Dec 02 Python
Python内置方法实现字符串的秘钥加解密(推荐)
Dec 09 Python
python 求10个数的平均数实例
Dec 16 Python
python3.8与pyinstaller冲突问题的快速解决方法
Jan 16 Python
解决 jupyter notebook 回车换两行问题
Apr 15 Python
解决pytorch多GPU训练保存的模型,在单GPU环境下加载出错问题
Jun 23 Python
详解解Django 多对多表关系的三种创建方式
Aug 23 Python
python实现的系统实用log类实例
Jun 30 #Python
python实现在windows服务中新建进程的方法
Jun 30 #Python
python实现线程池的方法
Jun 30 #Python
python实现的简单FTP上传下载文件实例
Jun 30 #Python
编写Python CGI脚本的教程
Jun 29 #Python
Python访问纯真IP数据库脚本分享
Jun 29 #Python
Python实现把数字转换成中文
Jun 29 #Python
You might like
PHP入门速成(2)
2006/10/09 PHP
PHP 网页过期时间的控制代码
2009/06/29 PHP
QQ登录 PHP OAuth示例代码
2011/07/20 PHP
基于magic_quotes_gpc与magic_quotes_runtime的区别与使用介绍
2013/04/22 PHP
PHP跨平台获取服务器IP地址自定义函数分享
2014/12/29 PHP
thinkphp5.0自定义验证规则使用方法
2017/11/16 PHP
PHP常用函数之根据生日计算年龄功能示例
2019/10/21 PHP
PHP设计模式之命令模式示例详解
2020/12/20 PHP
对象的类型:本地对象(1)
2006/12/29 Javascript
javascript 面向对象继承
2009/11/26 Javascript
JS 密码强度验证(兼容IE,火狐,谷歌)
2010/03/15 Javascript
js实现的跟随鼠标移动的时钟效果(中英文日期显示)
2011/01/17 Javascript
jquery post方式传递多个参数值后台以数组的方式进行接收
2013/01/11 Javascript
jQuery+.net实现浏览更多内容(改编php版本)
2013/03/28 Javascript
jQuery实现随意改变div任意属性的名称和值(部分原生js实现)
2013/05/28 Javascript
jquery中checkbox使用方法简单实例演示
2015/11/24 Javascript
node.js连接mongoDB数据库 快速搭建自己的web服务
2016/04/17 Javascript
基于原生JS实现图片裁剪
2016/08/01 Javascript
JavaScript中的call和apply的用途以及区别
2017/01/11 Javascript
jQuery中ztree 点击文本框弹出下拉框的实例代码
2017/02/05 Javascript
bootstrap table支持高度百分比的实例代码
2018/02/28 Javascript
vue-router重定向和路由别名的使用讲解
2019/01/19 Javascript
使用jQuery实现购物车
2020/10/29 jQuery
Python中%是什么意思?python中百分号如何使用?
2018/03/20 Python
Python之pandas读写文件乱码的解决方法
2018/04/20 Python
pandas数据清洗,排序,索引设置,数据选取方法
2018/05/18 Python
python 基本数据类型占用内存空间大小的实例
2018/06/12 Python
Python socket实现的简单通信功能示例
2018/08/21 Python
使用pandas把某一列的字符值转换为数字的实例
2019/01/29 Python
Python多线程获取返回值代码实例
2020/02/17 Python
基于Keras 循环训练模型跑数据时内存泄漏的解决方式
2020/06/11 Python
详解numpy.ndarray.reshape()函数的参数问题
2020/10/13 Python
TUMI澳大利亚网站:美国旅行箱包品牌
2017/03/27 全球购物
安全大检查实施方案
2014/02/22 职场文书
信用卡逾期证明示例
2014/09/13 职场文书
JavaWeb Servlet开发注册页面实例
2022/04/11 Java/Android