输入格式
- 第一行输入
一个加密或解密
; - 第二行输入
要加密或解密的文件名
; - 第三行输入
一个英文单词
。
输出格式
- 输入合法时输出
加密或解密后的文本
; - 输入非法时输出
输入错误
。
相关知识
Python 文件读写
open 函数
open()
函数用于打开一个文件,创建一个file对象,相关的方法才可以调用它进行读写。
语法
open(name[, mode[, buffering]])
参数说明
-
name: 一个包含了你要访问的文件名称的字符串值。
-
mode: mode决定了打开文件的模式:只读,写入,追加等。所有可取值见如下的完全列表。这个参数是非强制的,默认文件访问模式为只读(r)。
-
buffering: 如果buffering的值被设为0,就不会有寄存。如果buffering的值取1,访问文件时会寄存行。如果将buffering的值设为大于1的整数,表明了这就是的寄存区的缓冲大小。如果取负值,寄存区的缓冲大小则为系统默认。
def read_txt(file):
"""接收文件名为参数,读取文件中的内容为一个字符串,返回这个字符串。"""
with open(file, 'r') as temp:
return temp.read()
Python String 模块内置属性
string.ascii_lowercase
小写字母string.ascii_uppercase
大写字母string.digits
数字0 - 9
def caesar_decrypt(text, offset):
"""接收一个加密的字符串text和一个整数offset为参数,采用字母表和数字中前面第offset个字符
代替当前字符的方法对字符串中的字母和数字进行替换,实现解密效果,返回值为解密的字符串。"""
lower = string.ascii_lowercase # 小写字母
upper = string.ascii_uppercase # 大写字母
before = lower[offset:] + lower[:offset] + upper[offset:] + upper[:offset] + string.digits[offset:] + string.digits[:offset]
after = string.ascii_letters + string.digits
Python 常用函数
range
range()
函数返回的是一个可迭代对象(类型是对象),而不是列表类型, 所以打印的时候不会打印列表。
语法
range(stop)
range(start, stop[, step])
参数说明
-
start: 计数从start开始。默认是从0开始。例如range(3)等价于range(0, 3);
-
stop: 计数到stop结束,但不包括stop。例如:range(0, 3)是[0, 1, 2],没有3
-
step:步长,默认为1。例如:range(0, 3)等价于range(0, 3, 1)
def find_offset(key_text, ciphertext):
"""接收一个明文单词和一个加密字符串为参数,尝试用[0,8]之间的数为偏移量进行解密。
若解密结果中包含这个明文单词,说明当前正在尝试的偏移量就是加密时所用偏移量,返回
这个整数偏移量。
"""
offset = 0
for i in range(0, 9):
if key_text in caesar_decrypt(ciphertext, i):
offset = i
return offset
maketrans
maketrans()
方法用于创建字符映射的转换表,对于接受两个参数的最简单的调用方式,第一个参数是字符串,表示需要转换的字符,第二个参数也是字符串表示转换的目标。
语法
str.maketrans(intab, outtab)
参数说明
- intab - - 字符串中要替代的字符组成的字符串。
- outtab - - 相应的映射字符的字符串。
def caesar_cipher(text, offset):
"""接收一个字符串为参数,采用字母表和数字中后面第offset个字符代替当前字符的方法
对字符串中的字母和数字进行替换,实现加密效果,返回值为加密的字符串。
例如:2019 abc 替换为5342 def """
lower = string.ascii_lowercase # 小写字母
upper = string.ascii_uppercase # 大写字母
before = string.ascii_letters + string.digits
after = lower[offset:] + lower[:offset] + upper[offset:] + upper[:offset] + string.digits[offset:] + string.digits[
:offset]
table = ''.maketrans(before, after) # 创建映射表
return text.translate(table)
编程要求
本项目文件下载: text0.txt tests.txt jap.txt testjm.txt 在右侧编辑器中补充代码,完成文件分析与加密。具体要求如下:
1.接收一个字符串为参数,如果参数值为加密
, 要求用户输入一个要加密的文件名
,再输入一个单词做为密钥发生器
,用于计算偏移量,对文件中的内容进行加密并输出;
2.如果参数值为解密
, 要求用户输入一个要解密的文件名
,再输入一个单词做为匹配词
,用于破解偏移量,输出解密后的文本
;
3.若为其他输入,输出输入错误
。
4.为了提高加密强度,本题不使用固定偏移量,而是约定用一个英文单词做为密钥,读入一个英文单词,计算这个单词的每个字母的ASCII
值的和,再对9
取模,结果作为偏移量offset
。将大写字母、小写字母和数字均用其后的第offset
个字符代替,获得加密的文本。例如:当偏移量为3
的时候,所有的字母A将被替换成D
,B
替换成E
,以此类推。
5.解密处理进行相反的操作,不同的是,凯撒加密的强度不高,若知道明文中的一个单词,便可以直接根据这个单词进行暴力破解。
代码实现
import string
def judge(txt):
"""接收一个字符串为参数,如果参数值为“加密”,要求用户输入一个要加密的文件名,
再输入一个单词做为密钥发生器,用于计算偏移量,对文件中的内容进行加密并输出。
如果参数值为“解密”,要求用户输入一个要解密的文件名,再输入一个单词做为匹配词,
用于破解偏移量,输出解密后的文本。若为其他输入,输出'输入错误'。"""
###############################Begin#####################################
if txt == '加密':
file = input()
key_word = input()
print(caesar_cipher(read_txt(file), cal_offset(key_word)))
elif txt == '解密':
file = input()
key_text = input()
print(caesar_decrypt(read_txt(file), find_offset(key_text, read_txt(file))))
else:
print('输入错误')
################################End######################################
def read_txt(file):
"""接收文件名为参数,读取文件中的内容为一个字符串,返回这个字符串。"""
with open(file, 'r') as temp:
return temp.read()
def caesar_cipher(text, offset):
"""接收一个字符串为参数,采用字母表和数字中后面第offset个字符代替当前字符的方法
对字符串中的字母和数字进行替换,实现加密效果,返回值为加密的字符串。
例如:2019 abc 替换为5342 def """
###############################Begin#####################################
lower = string.ascii_lowercase # 小写字母
upper = string.ascii_uppercase # 大写字母
digit = string.digits # 数字
before = string.ascii_letters + digit
after = lower[offset:] + lower[:offset] + upper[offset:] + upper[:offset] + digit[offset:] + digit[:offset]
table = ''.maketrans(before, after)
caesar_cipher = text.translate(table)
return caesar_cipher
################################End######################################
def caesar_decrypt(text, offset):
"""接收一个加密的字符串text和一个整数offset为参数,采用字母表和数字中前面第offset个字符
代替当前字符的方法对字符串中的字母和数字进行替换,实现解密效果,返回值为解密的字符串。"""
###############################Begin#####################################
lower = string.ascii_lowercase # 小写字母
upper = string.ascii_uppercase # 大写字母
digit = string.digits # 数字
before = string.ascii_letters + digit
after = lower[offset:] + lower[:offset] + upper[offset:] + upper[:offset] + digit[offset:] + digit[:offset]
table = ''.maketrans(after, before)
decrypt_text = text.translate(table)
return decrypt_text
################################End######################################
def cal_offset(key_word):
"""接收一个单词为参数,计算这个单词的每个字母的ASCII值的和,
再对9取模,结果作为偏移量offset,返回这个偏移量。"""
###############################Begin#####################################
s = 0
for i in key_word:
s = s + ord(i)
offset = s % 9
return offset
################################End######################################
def find_offset(key_text, ciphertext):
"""接收一个明文单词和一个加密字符串为参数,尝试用[0,8]之间的数为偏移量进行解密。
若解密结果中包含这个明文单词,说明当前正在尝试的偏移量就是加密时所用偏移量,返回
这个整数偏移量。
"""
###############################Begin#####################################
offset = 0
for i in range(0,9):
if key_text in caesar_decrypt(ciphertext, i):
offset = i
return offset
################################End######################################
if __name__ == '__main__':
task = input()
judge(task)
测试说明
平台会对你编写的代码进行测试:
测试输入1: 加密
/step1/testks.txt
February
预期输出1: Fieyxmjyp mw fixxiv xler ykpc.Ibtpmgmx mw fixxiv xler mqtpmgmx.
测试输入2: 解密
/step1/testjm.txt
than
预期输出2: Beautiful is better than ugly.Explicit is better thanimplicit.