python实现凯撒密码加密与解密(暴力求解)

在密码学中,凯撒密码(英语:Caesar cipher),或称凯撒加密、凯撒变换、变换加密,是一种最简单且最广为人知的加密技术。它是一种替换加密的技术,明文中的所有字母都在字母表上向后(或向前)按照一个固定数目进行偏移后被替换成密文。
需求分析:
1、输入一行明文,使用凯撒加密方法对其加密,其中为保证加密的随机性,对Key进行随机处理。
2、对于加密后的密文,使用暴力搜索的方法对其进行解密,并调用字典对解密后的字词进行比较,自动选出正确的密匙。
例如:
在这里插入图片描述

先放一个不带UI界面的代码

from random import randint

import enchant
from enchant.checker import SpellChecker
import numpy as np
import string

#加密
def kaisa(s, k):  # 定义函数 接受一个字符串s 和 一个偏移量k

    lower = string.ascii_lowercase  # 小写字母
    upper = string.ascii_uppercase  # 大写字母
    before = string.ascii_letters  # 无偏移的字母顺序 小写+大写
    after = lower[k:] + lower[:k] + upper[k:] + upper[:k]  # 偏移后的字母顺序 还是小写+大写
    # 分别把小写字母和大写字母偏移后再加到一起
    table = ''.maketrans(before, after)  # 创建映射表
    return s.translate(table)  # 对s进行偏移 即加密

s = input('请输入一个字符串:')

k = randint(0,26) #从0-25中挑选随机一个数字当做偏移量
print(kaisa(s, k))

#解密

# message = input("message:")
message = kaisa(s,k)
LETTERS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
true_yuju = ""
tmp = np.ones((1,26))
# print(tmp)
# 把每个可能的密钥循环一遍
message = "GUVF VF ZL FRPERG ZRFFNTR"
for key in range(len(LETTERS)):
    # key代表密钥
    # translated设为空字符串
    # 每次循环后清空.
    translated = ''
    # 密文里的每一个字符按顺序解密
    for symbol in message:
        if symbol in LETTERS:
            num = LETTERS.find(symbol) # 在26个字母里搜索到密文字符的位置
            num = num - key
            # 检查是否小于0,如果小于0,就加上26
            if num < 0:
                num = num + len(LETTERS)
            # 把解密之后的字符追加到translated字符串的末尾
            translated = translated + LETTERS[num]

        else:
            # 密文里的symbol如果不在26个字母里,就不进行解密,直接追加到字符串末尾
            translated = translated + symbol

    # 输出解密采用的key和解密后的明文
    print('Key #%s: %s' % (key, translated))
    chkr = SpellChecker("en_US")
    chkr.set_text(translated)
    for err in chkr:
        if(err.word == None):
            true_yuju = translated
        else:
            tmp[0][key] = 0
    if(tmp[0][key] == 1):
        true_yuju = translated
print("正确的是: ",true_yuju)

再放一个带UI界面的代码:

import tkinter
from tkinter import *
# from project1 import kaisa
from random import randint
import string
import numpy as np
from enchant.checker import SpellChecker

def kaisa(s, k):  # 定义函数 接受一个字符串s 和 一个偏移量k

    lower = string.ascii_lowercase  # 小写字母
    upper = string.ascii_uppercase  # 大写字母
    before = string.ascii_letters  # 无偏移的字母顺序 小写+大写
    after = lower[k:] + lower[:k] + upper[k:] + upper[:k]  # 偏移后的字母顺序 还是小写+大写
    # 分别把小写字母和大写字母偏移后再加到一起
    table = ''.maketrans(before, after)  # 创建映射表
    return s.translate(table)  # 对s进行偏移 即加密

class MY_GUI():
    def __init__(self, init_window_name):
        self.init_window_name = init_window_name

    def set_init_window(self):
        self.init_window_name.title("凯撒密码")
        self.init_window_name.geometry('680x500+10+10')
        self.init_window_name.resizable(False, False)

        self.init_label = Label(self.init_window_name, text = "初始字符串: ", height = 2, width = 10,anchor="w")
        self.init_label.grid(row = 0, column = 0)
        self.encipher_label = Label(self.init_window_name, text = "加密后结果: ", height = 2, width = 10,anchor="w")
        self.encipher_label.grid(row = 1, column = 0)
        self.decipher_label = Label(self.init_window_name, text = "解密后结果: ", height = 2, width = 10,anchor="w")
        self.decipher_label.grid(row = 2, column = 0)

        self.init_data_Text = Text(self.init_window_name, height =1, width = 70)
        # self.init_data_Text.insert(1.0, "abc")
        self.init_data_Text.grid(row = 0, column = 1, padx = 5, pady = 5)
        self.encipher_data_Text = Text(self.init_window_name, width = 70, height = 1)
        self.encipher_data_Text.grid(row =1, column = 1)
        self.decipher_data_Text = Text(self.init_window_name, width = 70, height = 30)
        self.decipher_data_Text.grid(row = 2, column = 1, padx = 5, pady = 5,rowspan =30)
        self.encipher_button = Button(self.init_window_name, text= "加密", width=10, command=self.encipher)
        self.encipher_button.grid(row=0, column=11)
        self.decipher_button = Button(self.init_window_name, text="解密", width = 10, command = self.decipher)
        self.decipher_button.grid(row = 2, column = 11)

    def encipher(self):
        str = self.init_data_Text.get(1.0, END)
        k = randint(0, 26)
        encipher_text = kaisa(str, k)
        #encipher_text = "abc"
        self.encipher_data_Text.insert(1.0, encipher_text)
    def decipher(self):
        message = self.encipher_data_Text.get(1.0, END)
        LETTERS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
        true_yuju = ""
        tmp = np.ones((1, 26))
        # print(tmp)
        # 把每个可能的密钥循环一遍
        result = ""
        KEY = 0
        for key in range(len(LETTERS)):
            # key代表密钥
            # translated设为空字符串
            # 每次循环后清空.
            translated = ''
            # 密文里的每一个字符按顺序解密
            for symbol in message:
                if symbol in LETTERS:
                    num = LETTERS.find(symbol)  # 在26个字母里搜索到密文字符的位置
                    num = num - key
                    # 检查是否小于0,如果小于0,就加上26
                    if num < 0:
                        num = num + len(LETTERS)
                    # 把解密之后的字符追加到translated字符串的末尾
                    translated = translated + LETTERS[num]

                else:
                    # 密文里的symbol如果不在26个字母里,就不进行解密,直接追加到字符串末尾
                    translated = translated + symbol

            # 输出解密采用的key和解密后的明文
            print('Key #%s: %s' % (key, translated))
            result += "Key #" + str(key) + ": " + str(translated)
            result = result.strip('\n')
            result += '\n'
            chkr = SpellChecker("en_US")
            chkr.set_text(translated)
            for err in chkr:
                if (err.word == None):
                    true_yuju = translated
                else:
                    tmp[0][key] = 0
            if (tmp[0][key] == 1):
                true_yuju = translated
                KEY = key
        result += '\n' + '\n'
        true_yuju = "Key为: "+ str(KEY) + " 解密后的信息为: " + true_yuju
        result += true_yuju
        self.decipher_data_Text.insert(1.0, result)

def gui_start():
    init_window = Tk()
    ZMJ_PORTAL = MY_GUI(init_window)
    # 设置根窗口默认属性
    ZMJ_PORTAL.set_init_window()
    init_window.mainloop()  # 父窗口进入事件循环,可以理解为保持窗口运行,否则界面不展示
gui_start()

猜你喜欢

转载自blog.csdn.net/weixin_45807161/article/details/123586905