本文附有丰富的代码,故文章冗长,请对照目录查阅,各大板块均有上下文提示

目录

古典密码简介

仿射变换:

多表代换:

1.加密算法基础准备

2.仿射变换加密类的实现

3.多表代换加密类的实现

例题:仿射变换加密

例题:多表代换加密


古典密码简介

古典密码主要有置换和代换的方法。置换:字母重新排列,字母本身不变,但其位置改变了(凯撒密码、移位变换)。代换:将明文中的字符替代成其他字符(仿射变换、多表代换)。

在线性空间的变化中,古典加密就是移动并拉伸物体,让物体变得与原来不一样;解密解释将物体移动回去拉伸回去,恢复物体的原样。

凯撒密码 移位变换 仿射变换可以理解为单表代换,这三种古典密码实质上可以归根于多表代换的特殊形式——单表代换,即一个字母一组。

在此文中,考虑到凯撒密码、移位密码的简单性,仅介绍仿射变换、多表代换加密。加密算法的详细内容请自行查阅,以下仅列出变换公式

仿射变换:

加密:

解密:

其中为密钥,且满足, 的乘法逆元。

多表代换:

将n个字母长的明文M分成M1,M2···Mi对每个分组:

加密:

解密: 

 为密钥,的可逆矩阵(即),且满足为密文分组。

1.加密算法基础准备

在这两种古典加密中最重要的是求逆元,即  的乘法逆元  的加密逆元 。两个逆元均用扩展欧几里得法。因此将扩展欧几里得、求逆元等算法封装在 类MathUitl 仿射变换、多表代换等加解密算法封装在 类TransAlgor 中,以供加解密使用。另一个 类IintiDeal 用与处理密钥输入等,现在不用关心。重要的地方均有注解,没注解就是你也一定会看懂!

# 本代码文件名:__util.pyimport numpy as npclass MathUtil():""" 数学运算工具类 """def extendGcd(a, b):"""扩展欧几里德算法"""if b == 0:return 1, 0else:x, y = MathUtil.extendGcd(b, a % b)x, y = y, x - (a//b) * yreturn x, ydef modInvElem(a:int, m=26):"""求整数a关于1模m的乘法逆元"""if (np.gcd(a, m) !=1): return -1inva, _ = MathUtil.extendGcd(a, m)inva %= mreturn invadef modInvMatrix(A, m=26):"""求矩阵A关于1模m的乘法逆元"""detA = np.linalg.det(A)invA = np.linalg.inv(A)Adjoint = detA * invAinv_detA = MathUtil.modInvElem(round(detA), m)cipher_invA = ((inv_detA % m) * Adjoint) % mcipher_invA = np.round(cipher_invA).astype(int)return cipher_invAclass TransAlgor():""" 变换算法工具类 """def affine(code, A, B, m=26):"""仿射变换1模26算法"""return (A * code + B) % mdef invAffine(code, invA, B, m=26):"""仿射变换1模26逆算法"""return invA * (code - B) % mdef polyalphabet(code:list, A, B, m=26) -> list:"""多表代换1模26算法"""group_len = len(B)code = np.mat(code).reshape(group_len,1)C = ((np.dot(A, code) + B) % m).reshape(-1)C = C.tolist()[0]return Cdef invpolyalpha(code:list, invA, B, m=26) -> list:"""多表代换1模26逆算法"""group_len = len(B)code = np.mat(code).reshape(group_len, 1)M = (np.dot(invA, (code - B)) % m).reshape(-1)M = M.tolist()[0]return Mclass InitDeal():""" 键盘输入处理类 """def inputKey() -> list:""" 用户从键盘输入密钥 """keyA = [[*map(eval, input("\n请输入n阶密钥方阵A:\n").split())]]for _ in range(len(*keyA) - 1):keyA.append([*map(eval, input().split())])keyB = [*map(eval, input("\n请输入n维密钥向量B:\n").split())]key = [keyA, keyB]return keydef keyProcess(inputkey):""" 输入密钥进行处理->逆元cipher_invA等密钥 """A, B = inputkeygroup_len = len(B)A = np.mat(A).reshape(group_len,group_len)B = np.mat(B).reshape(group_len,1)try: cipher_invA = MathUtil.modInvMatrix(A)except: return Falsekeylist = [A, B, cipher_invA]return keylistdef dealText(textstr, group_len):""" 将文本进行分组处理@textstr: 字符串文本@group_len: 分组长度"""# 文本字符串去空格, 长度用z补全, 如"abcabc" textstr = textstr.replace(" ", "")blank = len(textstr) % group_lenif blank != 0:textstr = textstr + (group_len-blank) * "z"# 统一转换成小写0~25编码列表, 如[0,1,2,0,1,2]textlist = list(textstr.lower())codelist = [ord(i)-97 for i in textlist]# 将编码列表进行分组, 即编码子向量, 如[[0,1,2],[0,1,2]]codegroup = []for i in range(0, len(codelist), group_len):codegroup.append(codelist[i:i+group_len])return codegroupclass HerkCode():""" 自定义编码类 """def enCode(text):""" 53编码 by Herk@text: 待编码的字符串, 如"abc"@return: 对应的编码流, 即"010203""""pool = " abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"code = [(2-len(str(pool.index(i))))*'0'+str(pool.index(i)) for i in text]return ''.join(code)def deCode(code):""" 53解码 by Herk@code: 待解码的数字流, 如"010203"@return: 对应的字符串, 即为"abc""""pool = " abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"text = [pool[int(code[i:i+2])] for i in range(0, len(code), 2)]return ''.join(text)

2.仿射变换加密类的实现

# 本代码文件名: affine.py
# 导入上面基础准备写好的类from __util import *class AffineCipher():""" 仿射变换加密 """def __init__(self, inputkey=None):""" 密钥初始化构建@inputkey: 例如[1, 3]若密钥为空则从键盘输入"""self.inputkey  = inputkeyself.buildKey()def buildKey(self):""" 生成相关密钥数据 """if self.inputkey == None:tips = "输入一对密钥: "      # 例如输入: 1 3 self.inputkey = [*map(eval, input(tips).split())]self.A, self.B = self.inputkey # 处理输入密钥, 得到密钥a,bself.invA = MathUtil.modInvElem(self.A) # 计算密钥a的逆元def enCrypt(self, messag):""" 仿射变化加密@messag: 明文字符串@return: 密文字符串"""codelist = []cipherlist = []for i in messag:codelist.append(ord(i))for i in codelist:if 65 <= i <= 90:i -= 65i = TransAlgor.affine(i, self.A, self.B) + 65elif 97 <= i <= 122:i -= 97i = TransAlgor.affine(i, self.A, self.B) + 97cipherlist.append(chr(i))ciphertext = ''.join(cipherlist)return ciphertextdef deCrypt(self, cipher):""" 仿射变换解密@cipher: 密文字符串@return: 明文字符串"""codelist = []plainlist = []for i in cipher:codelist.append(ord(i))for i in codelist:if 65 <= i <= 90:i -= 65i = TransAlgor.invAffine(i, self.invA, self.B) + 65elif 97 <= i <= 122:i -= 97i = TransAlgor.invAffine(i, self.invA, self.B) + 97plainlist.append(chr(i))plaintext = ''.join(plainlist)return plaintextif __name__ == '__main__':crypto = AffineCipher()messag = input("输入明文: ")print("加密结果:", crypto.enCrypt(messag))cipher = input("输入密文: ")print("解密结果:", crypto.deCrypt(cipher))

3.多表代换加密类的实现

# 本代码文件名: polyalphabet.py
# 导入上面基础准备写好的类from __util import *class PolyalphabetCipher():""" 多表代换加密 """def __init__(self, inputkey=None):""" 实例化类时需要复写的属性 """self.inputkey  = inputkeyself.buildKey()def buildKey(self):""" 实例化对象后 必须构建密钥 """if self.inputkey == None:self.inputkey = InitDeal.inputKey()key = InitDeal.keyProcess(self.inputkey)self.A, self.B, self.invA = keydef enCrypt(self, plaintext):""" 加密算法 返回密文 """ciphertext = ""codegroup = InitDeal.dealText(plaintext, len(self.B))for group in codegroup:group = TransAlgor.polyalphabet(group, self.A, self.B)group = [chr(i+97) for i in group] # 密文编码->字母串列表group = ''.join(group)             # 字母串列表->密文串ciphertext = ciphertext + group + " "return ciphertextdef deCrypt(self, ciphertext):""" 加密算法 返回明文 """plaintext = ""codegroup = InitDeal.dealText(ciphertext, len(self.B))for group in codegroup:group = TransAlgor.invpolyalpha(group, self.invA, self.B)group = [chr(i+97) for i in group] # 明文编码->字母串列表group = ''.join(group)             # 字母串列表->明文串plaintext = plaintext + group + " "return plaintextif __name__ == '__main__':crypto = PolyalphabetCipher()plaintext = input("输入明文: ")print("加密结果:", crypto.enCrypt(plaintext))ciphertext = input("输入密文: ")print("解密结果:", crypto.deCrypt(ciphertext))

例题:仿射变换加密

from affine import *key = [7, 21]
messag = "security"
cipher = "vlxijh"crypto = AffineCipher(key)
print("仿射变换密钥对为: 7 21")
print("security 加密为:", crypto.enCrypt(messag))
print("vlxijh   解密为:", crypto.deCrypt(cipher))

例题:多表代换加密

from polyalphabet import *keyA = [[11, 2, 19],[5, 23, 25],[20, 7, 17]]
keyB =  [ 0, 0,  0]# 实例化加密对象, 并传入参数进行构建
key = [keyA, keyB]
plaintext  = "your pin no is four one two six"
ciphertext = "wgi fgj tmr lhh xth wbx zps brb"crypto = PolyalphabetCipher(key)
print("密钥为:", key)
print("加密为:", crypto.enCrypt(plaintext))
print("解密为:", crypto.deCrypt(ciphertext))

【古典密码】 凯撒密码 移位变换 仿射变换 多表代换 Python相关推荐

  1. 移位密码(凯撒密码)

    一.移位密码(凯撒密码) 移位密码是一种简单的加密方法,它通过将明文中的每个字符按照一定规则向左或向右移动若干位来生成密文.移位密码通常使用偏移量来确定每个字符移动的位数. 二.加密解密 1. 移位加 ...

  2. python编写凯撒密码的加密函数_python实现 古典密码 凯撒密码的加密与解密

    python实现 古典密码 凯撒密码的加密与解密 实现效果如下图: # 凯撒密码加密与解密 # author Sundm string = ['a','b','c','d','e','f','g',' ...

  3. 古老密码---凯撒密码

    将替代密码用于军事用途的第一个文件记载是恺撒著的<高卢记>.恺撒描述了他如何将密信送到正处在被围困.濒临投降的西塞罗.其中罗马字母被替换成希腊字母使得敌人根本无法看懂信息.苏托尼厄斯在公元 ...

  4. C++实现古典密码-凯撒密码加密解密算法

    文章目录 第一部分 Caesar密码简介 1.1 基本思想 1.2 历史沿革 第二部分 Caesar密码的C++实现 第一部分 Caesar密码简介 1.1 基本思想 在密码学中,恺撒密码(英语:Ca ...

  5. C语言凯撒密码字母向后偏移三位,凯撒加密解密(java字母移位)

    1.设计思想:加密就是将字符数据转化为ASC码表中的数字,a-w之间通过加3之后再转化为字符型输出,x-z之间通过转化为ASC码表中的数字后减去23再转化为字符型输出.解密就是将字符数据转化为ASC码 ...

  6. java密码框转字符串_实现汉字的凯撒密码(内容包括:去掉字符串中的转义字符、汉字的unicode转换)...

    实验内容: 选择合适的秘钥,利用上述三个算法:熟悉恺撒密码.双重置换密码.一次一密密码算法.加密如下明文: 大风起兮云飞扬, 威加海内兮归故乡, 安得猛士兮守四方. <大风歌>--刘邦 3 ...

  7. 【密码学-凯撒密码】

    现代密码学-单表代换密码 凯撒密码原理 移位变换 仿射变换 代码实现-凯撒密码 代码实现-放射变换 凯撒密码原理 凯撒密码的加密代换和解密代换分别为 c=Ek(m)=m+3(mod26)c=E_{k} ...

  8. rust(58)-凯撒密码

    在密码学中,凯撒密码(英语:Caesar cipher),或称凯撒加密.凯撒变换.变换加密,是一种最简单且最广为人知的加密技术.它是一种替换加密的技术,明文中的所有字母都在字母表上向后(或向前)按照一 ...

  9. 凯撒密码的自动化破解方法(适用于英文文本)

    凯撒密码的自动化破解方法(适用于英文文本) 凯撒密码 凯撒加密是有记载的最古老的加密方法.原始的凯撒密码没有密钥,加密方式很原始,就是通过将字母表循环右移三位进行加密:a被D替代,b被E替代,-,x被 ...

  10. playfair密码和凯撒密码加密算法的Java实现

    文章目录 一.实现广义的凯撒密码加密算法 二.实现广义的playfair密码的加密算法 总结 加密原理: 一.实现广义的凯撒密码加密算法 //实现广义的凯撒密码//凯撒密码的加密String plai ...

最新文章

  1. Andraoid 状态栏透明的方法
  2. 安卓蓝牙调试软件和微信小程序搜索不到设备
  3. Linux SPI总线和设备驱动架构之三:SPI控制器驱动
  4. ODI中web service介绍
  5. mysql数据库的后_MySQL数据库误删后的回复技巧
  6. Vue项目中的初始化
  7. Preloading组件。
  8. Eclipse和PyDev搭建完美Python开发环境(Windows篇)
  9. 事故现场:MySQL 中一个双引号的错位引发的血案
  10. 装饰画必备素材——装饰设计师,填充不用愁!
  11. 美国数学家维纳智力早熟,11岁就上了大学,他曾在1935-1936年 应邀参加中国清华大学讲学,一次他参加某个重要会议,年轻的脸孔 引人注意,于是有人询问他的年龄,他回答说“我年龄的立方是个4位数
  12. w10查看端口_win10系统使用dos命令查看端口的解决教程
  13. 数字电路基础-逻辑门电路
  14. 利用checked实现收藏按钮红心的显示与隐藏
  15. 目标与计划:仰望星空且脚踏实地
  16. 解决SQLServer2000安装被挂起的方法
  17. 内存申请 GFP_KERNEL GFP_ATOMIC
  18. day16re模块和面向对象
  19. STM32要按复位键才能下载问题解决
  20. 04、Netty学习笔记—(黏包半包及协议设计解析)

热门文章

  1. PDF图形(PDF graphics)
  2. Ubuntu 上 ibus 拼音输入法(打字法)无法选词 BUG 的解决方案
  3. Qt 酷炫动画 PictureFlow
  4. ChartDirector画2D,3D图,MFC画图
  5. java鼠标变粗怎么办_java – 使用Apache POI使整行变粗
  6. c串口一直读到缓存数据_STM32CubeMX之串口不定长数据接收(接收中断+空闲中断)...
  7. 《线性代数及其应用》笔记-第三章
  8. mysql 2008 教程_sql 2008 视频教程数据库从入门到精通自学视频教程_IT教程网
  9. 《Go Web编程实战派——从入门到精通》学习笔记之第1章 Go基础入门
  10. 用友nc系统服务器是云端吗,用友NC服务器硬件配置要求