仿射密码实验——Python实现(完整解析版)


前言

实验目的
1)初步了解古典密码
2)掌握仿射密码的实现

实验方法
根据下图仿射密码(变换)加解密的描述,用所熟悉的语言,完成实验内容、描述实验操作步骤、实验结果与实验心得。

实验环境
计算机语言:Python
开发环境:Pycharm


原理
在这里插入图片描述

实验内容

  1. 编程实现仿射密码,要求有加密步骤和解密步骤。若输入参数a,b不合法,则报错。
  2. 提供两种解密方法,一是掌握密钥破解,而是无密钥的暴力破解
  3. 使用两种加解密的操作,一是命令行的输入输出,而是文件的读取写入生成
  4. 加解密过程中应考虑大小写

实验操作步骤

1.编写主程序

在main主程序里,需要有相应的功能提示

作为菜单栏使用
不同的数字对应实现不同的功能:1加密2解密3文件形式加解密4退出程序
在这里插入图片描述

2.编写加密模块

需求有:提示输入明文和密钥,对明文进行仿射密码方式的加密,最后输出
在这里插入图片描述

m接收用户输入的明文
c作为数组来存储,a和b就是密钥需要用户提供
对于输入的a和b需整形化,然后判断a、b是否互素通过ab的最大公因数是否为1判断
若不互素则提示用户重新输入

达成互素条件后
首先采用正则表达式处理一下用户输入一些特殊符号
(如果不处理的话,那么形成的密文最后也是解密不了的)
接着采用replace去除空格
进入encrypt模块
在这里插入图片描述

在这个模块中,原理就是将之前用户输入的参数m,a,b传入
然后通过先转化成ascii码和进行模运算,这里计算得到的ascii码chr后,得到的是大写的英文字母,为此最后输出的时候提供给用户两种结果:大写和小写

3.编写解密模块

首先提示输入密文,考虑之前我们加密后的结果一般都是只有英文字母的组合
这里我就只有进行大小写的处理
提示用户是否知道密钥,若有则接受参数a和b,同样得判断a,b是否互素来确认密钥的合法性
然后由a计算出k,再传入decrypt模块解密
在这里插入图片描述

解密其实就是加密数学上的逆运算
这里刚刚好相反,通过一系列计算得到的是一串小写英文字母
那与之前一样,我们需要给用户提供大写和小写的结果
在这里插入图片描述

假如选择不知道密钥的话,那么就是采用暴力破解
也就是数字组合一个个试,这里通过对仿射原理的理解便可以缩小点范围
定义的la数组和lb数组分别如图

4.编写文件加解密模块

在这里插入图片描述
这个文件我命名为usefile.py,并且作为库来给之前的脚本代码引用
在这里插入图片描述
这个文件其实和之前的代码以及实现的功能差不多
不过为了代码看起来不那么冗长,就单独再写一个模块了
以下是该代码的展示

密钥的输入
在这里插入图片描述

互素条件的判断
在这里插入图片描述
逆元的求解
在这里插入图片描述
文件加密
在这里插入图片描述

文件解密
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

主函数模块
在这里插入图片描述

实验结果

开始使用程序
运行script.py
在这里插入图片描述

输入数字1
在这里插入图片描述
我们用hello作为例子,密钥就为3和4吧
在这里插入图片描述
得到密文为ZQLLU 或 zqllu
在这里插入图片描述
这次试一下特殊符号
输入hell,,!!o
可以看到加密结果与之前一致
在这里插入图片描述
那我们现在试着解密
输入之前的密文zqllu,先按照有密钥解密
在这里插入图片描述
得到hello说明正确
再试一下无密钥暴力破解
在这里插入图片描述
这一次故意输入大写的ZQLLU,然后寻找一下正确的明文
在这里插入图片描述
Ok,与我们之前有密钥解出来结果一致,说明代码可行
好的,我们来看看文件模块运行如何
在这里插入图片描述
出现usefile里特有的菜单模块
事先我创建了一个test.txt,里面内含明文hello
运行功能1看看

在这里插入图片描述
在这里插入图片描述
然后当前目录下多了ciphertext.txt文件,查看该文件
在这里插入图片描述
结果没错
我们再试解密功能
在这里插入图片描述
该目录下多出plaintext.txt文件,查看该文件
在这里插入图片描述

还原成功,是明文hello
这里是提供了密钥,如果暴力破解就是和之前script文件中一致

实验心得

作为古典密码的一种,仿射密码的原理其实挺简单的,所以这次使用python来实现关于仿射密码的加解密难度不大,中间遇到的一些问题还是让我收获不少:加解密时要注意英文字母大小写、特殊符号需要处理、chr和ord的配合使用、编写不同的函数模块和文件来实现CLI版的功能等等,让我对于python的使用更加的得心应手。

很喜欢python的话语:人生苦短,我用python。
希望之后继续使用python解决有关密码学的问题。

实验源码

scirpt.py

# 暴力破解
import usefile as u
import re

la = [1, 3, 5, 7, 9, 11, 15, 17, 19, 21, 23, 25]
lb = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
      14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25]

# 最大公约数
def gcd(a, b):
    while b != 0:
        tem = a % b
        a = b
        b = tem
    return a

# 加密
def encrypt(m, c, a, b):
    for i in range(len(m)):
        # 加密成相应的大写字母
        c.append(chr(((ord(m[i]) - 97) * a + b) % 26 + 65))
    d = ''.join(c)
    print(d,"或 {}".format(d.lower()))

# 求逆元
def niyuan(a, b):
    ny = 1
    while (a * ny) % b != 1:
        ny += 1
    return ny

# 解密
def decrypt(c, k, b):
    mw = []
    for i in range(len(c)):
        tem = ord(c[i]) - 65 - b
        if tem < 0:
            tem += 26
        mw.append(chr((k * tem) % 26 + 97))
    print("k=" + str(k) + ", b=" + str(b) + "时,解密后的明文为:")
    res = ''.join(mw)
    print(res,"或 {}".format(res.upper()))

def jiami():
    m = input("请输入明文:")
    c = []
    x, y = input("请输入a和b: ").split()
    a = int(x)
    b = int(y)
    while gcd(a, b) != 1:
        x, y = input("a和b不互素,请重新输入a和b: ").split()
        a = int(x)
        b = int(y)
    print("明文内容为:")
    print(m)
    r = "[!!+-=——,,。??、]"
    m = re.sub(r, ' ', m)
    m = m.replace(' ', '')
    print("加密后的密文为:")
    encrypt(m, c, a, b)


def jiemi():
    m = input("请输入密文:")
    c = []
    q = input("是否有密钥,有请输入1,无则输入0:")
    print("密文内容为:")
    print(m)
    if int(q)==1:
        x, y = input("请输入a和b: ").split()
        a = int(x)
        b = int(y)
        while gcd(a, b) != 1:
            x, y = input("a和b不互素,请重新输入a和b: ").split()
            a = int(x)
            b = int(y)
        m = m.upper()
        for i in range(len(m)):
            # 加密成相应的大写字母
            c.append(m[i])
        print("知道密钥破解:")
        k = niyuan(a, 26)
        decrypt(c, k, b)

    elif int(q)==0:
        m = m.upper()
        # 加密成相应的大写字母
        for i in range(len(m)):
            c.append(chr(ord(m[i])))
        print("不知道秘钥破解,暴力破解如下: ")
        for i in range(0, 12):
            for j in range(0, 26):
                decrypt(c, la[i], lb[j])

#实现
if __name__ == "__main__":
    # 明文
    while True:
        print("-------------------------")
        print("1.仿射密码加密")
        print("2.仿射密码解密")
        print("3.文件仿射加解密")
        print("4.程序退出")
        n = input("请输入功能对应的数字:")
        print("-------------------------")
        if int(n)==1:
            jiami()
        elif int(n)==2:
            jiemi()
        elif int(n)==3:
            u.main()
        elif int(n)==4:
            print("感谢使用!")
            break
        else:
            print("输入有误,请重新输入!")

usefile.py

#仿射密码加密与解密实现算法
# -*- coding=utf-8 -*-

#输入密钥
def accept():
	k1,k2 = map(int,input('请输入两个密钥(以空格隔开):').split())
	while gcd(k1, 26) !=1:
		k1,k2 = map(int,input('k1和26不互素,请重新输入密钥:').split())
	return k1,k2

#判断互素
def gcd(k1,m):
	t = 0
	while m!=0:
		t = m
		m = k1%m
		k1 = t
	return k1

#求逆元
def niyuan(k1):
	n = 1
	while (k1 * n) % 26 != 1:
		n += 1
	return n

#加密算法
def encrypt():
	#输入密钥
	k1,k2 = accept()
	n = input("请输入当前目录下需要加密文件名:")
	f = open(n)
	plain = f.read()
	#print(plain)
	c = []
	for i in range(len(plain)):
		#小写字母
		if plain[i].islower():
			c.append(chr(((ord(plain[i])-97)*k1+k2)%26+97))
		#大写字母
		elif plain[i].isupper():
			c.append(chr(((ord(plain[i])-65)*k1+k2)%26+65))
		#其他
		else :
			c.append(plain[i])

	cipher = ''.join(c)
	w = open('ciphertext.txt','w')
	w.write(cipher)
	print('加密完成!')
	f.close()
	w.close()

#解密算法
def decrypt():
	#输入密钥
	k1,k2 = accept()
	#逆元
	ny = niyuan(k1)
	str = input("请输入当前目录下需要解密文件名:")
	f = open(str)
	cipher = f.read()
	p = []
	for i in range(len(cipher)):
		#小写字母
		if cipher[i].islower():
			t1 = ord(cipher[i])-97-k2
			if t1 < 0:
				t1 +=26
			p.append(chr((ny * t1)%26+97))
		#大写字母
		elif cipher[i].isupper():
			t2 = ord(cipher[i])-65-k2
			if t2 < 0:
				t2 +=26
			p.append(chr((ny * t2)%26+65))
		#其他
		else :
			p.append(cipher[i])

	plain = ''.join(p)
	w = open('plaintext.txt','w')
	w.write(plain)
	print('解密完成!')
	f.close()
	w.close()

def main():
	while True:
		print("--------文件加解密操作--------")
		print("加密【1】:")
		print("解密【2】:")
		print("退出【3】:")
		ch = int(input("请输入对应功能数字:"))
		if ch == 1:
			encrypt()
		elif ch == 2:
			decrypt()
		elif ch == 3:
			print("感谢使用!")
			exit()
		else:
			print("请输入1或2")

  • 18
    点赞
  • 97
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值