古典密码学教学

一.目录
0x01.常见的古典密码
1.凯撒密码
2.栅栏密码
3.猪圈密码
4.埃特什码
5.希尔密码
6.培根密码
7.QWE密码/键盘密码
8.enigma密码
9.摩斯密码
10.跳舞的小人
0x02.凯撒密码
恺撒密码(恺撒加密、恺撒变换、变换加密),是一种最简单且最广为人知的加密技术。它是一种替换加密的技术,明文中的所有字母都在字母表上向后(或向前)按照一个固定数目进行偏移后被替换成密文。例如,当偏移量是3的时候,所有的字母A将被替换成D,B变成E,以此类推。
代码实现,此处使用python来实现:
plaincode= input("请输入明文:") for p in plaincode: if ord("a") <= ord(p) <= ord("z"): print(chr(ord("a")+(ord(p)-ord("a")+3)%26),end='') else: print(p,end='')

0x03.栅栏密码
①把将要传递的信息中的字母交替排成上下两行。
②再将下面一行字母排在上面一行的后边,从而形成一段密码。
③例如:
明文:THE LONGEST DAY MUST HAVE AN END
加密:
1、把将要传递的信息中的字母交替排成上下两行。
T E O G S D Y U T A E N N
H L N E T A M S H V A E D
2、 密文:
将下面一行字母排在上面一行的后边。
TEOGSDYUTAENN HLNETAMSHVAED
解密:
先将密文分为两行
T E O G S D Y U T A E N N
H L N E T A M S H V A E D
再按上下上下的顺序组合成一句话
明文:THE LONGEST DAY MUST HAVE AN END
python代码实现:
`def encode():
hang1 = []
hang2 = []
string = input('请输入要加密的字符串:')
li = list(string) # 将字符串转换为列表
# print(li)
for i in range(0, len(li)): # 循环遍历列表长度
if i % 2 == 0: # 模2取余
hang1.append(li[i])
# print(hang1)
else:
hang2.append(li[i])
he = hang1 + hang2 # 列表连接
print('加密成功,密文为:')
# print(he)
for i in he:
print(i, end='') # 遍历输出he,end为空(不换行)

def decode():
hang1 = []
hang2 = []
string = input('请输入要解密的字符串:')
li = list(string) # 将字符串转换为列表
for i in range(0, len(li)): # 循环遍历列表长度
if i % 2 == 0: # 模2取余
hang1.append(li[i])
else:
hang2.append(li[i])
he = hang1 + hang2 # 列表连接
print('解密成功,明文为:')
for i in he:
print(i, end='') # 遍历输出he,end为空(不换行)

if name == 'main':
def start():
print('*栅栏密码')
print('请选择功能:1.加密 2.解密 3.退出')
print('请输入数字以选择:')
choose = input()
if choose == '1': # 条件选择
encode()
elif choose == '2':
decode()
else:
exit()

start()  # 首次方法调用
while input('请输入是否继续(y/n):') == 'y':  # 循环方法调用
    start()`


0x03.猪圈密码
猪圈密码(Pigpen cipher,亦称朱高密码、共济会密码)是一种以格子为基础的简单替代式密码。即使使用符号,也不会影响密码分析,亦可用在其它替代式的方法。
早在1700年代,共济会常常使用这种密码保护一些私密纪录或用来通讯,所以又称共济会密码。

0x04.埃特什码
埃特巴什码(字母对应,首尾-尾首对应0)
埃特巴什码(Atbash Cipher)是由熊斐特博士发现的密码,其最后一个字母代表第一个字母,倒数第二个字母代表第二个字母,在公元一世纪的艾赛尼/萨多吉/拿撒勒教派的经文中用以隐藏姓名。
埃特巴什码在公元前500年就被抄经人用来写作《耶利米书》,它也是希伯来文所用的数种密码系统之一。
埃特巴什码(Atbash Cipher)是一个系统:最后一个字母代表第一个字母,倒数第二个字母代表第二个字母。
在罗马字母表中,它是这样出现的:
常文:A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
密文:Z Y X W V U T S R Q P O N M L K J I H G F E D C B A

python代码实现1:
`#列表对比
MINwen = [
'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z']

创建明文加密列表

JIAMI = [
'z','y','x','w','v','u','t','s','r','q','p','o','n','m','l','k','j','i','h','g','f','e','d','c','b','a'
] #创建密文解密列表
choose = input("选择E加密,选择D解密 ") #此处进行一个加密/解密的选择,使用if语句
if choose == 'E': #输入E进行加密运算
s1=input('输入需要加密的内容: ') #输入需要加密的内容

s1list = '' #设置一个空字符

for m in s1:  #m在s1中依次循环,相对比
    for i in range(0,26): #设置i对应的位置在(0,26),并且遍历,二次循环
        if m == MINwen[i]:  #判断条件,将m的值与MINwen表中i位置的值进行对比
            s1list += JIAMI[i] #条件满足之后,才执行该语句,也就是依次对比,直到相同为止
            break #跳出本次循环
print('此次加密结果为:')  #打印加密的结果
print(s1list) #打印加密的结果

if choose =='D': #输入D进行解密
s2 = input('输入要解密的内容: ') #输入需要解密的内容
s2list='' #设置一个空字符
for n in s2: #n在s2中依次循环,相对比
for i in range(0,26): #设置i对应的位置在(0,26),并且遍历,二次循环
if n == JIAMI[i]: #判断条件,将n的值与JIAMI表中i位置的值进行对比
s2list +=MINwen[i] #条件满足之后,才执行该语句,也就是依次对比,直到相同为止
break #跳出本次循环
print(s2list)

代码实现2:
`CODE_TABLE = { #加密字典
'z': 'a', 'y': 'b', 'x': 'c', 'w': 'd', 'v': 'e', 'u': 'f', 't': 'g',
's': 'h', 'r': 'i', 'q': 'j', 'p': 'k', 'o': 'l', 'n': 'm', 'm': 'n',
'l': 'o', 'k': 'p', 'j': 'q', 'i': 'r', 'h': 's', 'g': 't',
'f': 'u', 'e': 'v', 'd': 'w', 'c': 'x', 'b': 'y', 'a': 'z',
}

choose=input("输入D进行加密/输入E进行解密: ") #进行选择
if choose == 'D': #加密
s1=input("请输入要加密的内容:") #输入需要加密的内容
s1list='' #定义一个空字符
for i in s1: #依次遍历s1,将其值一个一个赋给i
if i in CODE_TABLE.values(): #将i的值在加密表中进行对比
s1list += list(CODE_TABLE.keys())[list(CODE_TABLE.values()).index(i)] #通过键值对在字典中进行寻找对应的数值
print(s1list) #输出打印字符集合
print(s1list.upper()) #将要打印输出的字符进行大写
if choose =='E': #选择E进行解密
s2= input("请输入要解密的内容:") #输入需要解密的内容
lists2=[] #定义一个列表,输出就输出列表的形式,也可以设置空字符
for i in range(0,len(s2),5): #将输入的内容,以5个字符划分为一个单位
lists2.append(s2[i:i+5]) #按照输入的内容依次以5个字符为1单位放在列表中
for i in range(len(lists2)): #确定列表的长度
lists2[i]=CODE_TABLE[lists2[i]] #将表中的以5个字符为1单位的,于字典进行匹配
print(''.join(lists2)) #打印输入解密的结果
print(''.join(lists2).upper()) #将要打印输出的字符进行大写 'g':'t', 'l:'o','k':'p','j':'q','i':"r","h":'s','g':'t',
#'e':'v','d':'w','c':'x','b':'y','a':'z',`

0x05.希尔密码
解密思路:需要用到矩阵,逆矩阵

详情参考链接:http://bobao.360.cn/ctf/learning/136.html
python代码实现暂无
0x06.培根密码


python代码实现:
CODE_TABLE = { #培根字典 'aaaaa':'a','aaaab':'b','aaaba':'c','aaabb':'d','aabaa':'e','aabab':'f','aabba':'g', 'aabbb':'h','abaaa':'i','abaab':'j','ababa':'k','ababb':'l','abbaa':'m','abbab':'n', 'abbba':'o','abbbb':'p','baaaa':'q','baaab':'r','baaba':'s','baabb':'t','babaa':'u', 'babab':'v','babba':'w','babbb':'x','bbaaa':'y','bbaab':'z', } choose=input("输入D进行加密/输入E进行解密: ") #进行选择 if choose == 'D': #加密 s1=input("请输入要加密的内容:") #输入需要加密的内容 s1list='' #定义一个空字符 for i in s1: #依次遍历s1,将其值一个一个赋给i if i in CODE_TABLE.values(): #将i的值在加密表中进行对比 s1list += list(CODE_TABLE.keys())[list(CODE_TABLE.values()).index(i)] #通过键值对在字典中进行寻找对应的数值 print(s1list) #输出打印字符集合 print(s1list.upper()) #将要打印输出的字符进行大写 if choose =='E': #选择E进行解密 s2= input("请输入要解密的内容:") #输入需要解密的内容 lists2=[] #定义一个列表,输出就输出列表的形式,也可以设置空字符 for i in range(0,len(s2),5): #将输入的内容,以5个字符划分为一个单位 lists2.append(s2[i:i+5]) #按照输入的内容依次以5个字符为1单位放在列表中 for i in range(len(lists2)): #确定列表的长度 lists2[i]=CODE_TABLE[lists2[i]] #将表中的以5个字符为1单位的,于字典进行匹配 print(''.join(lists2)) #打印输入解密的结果 print(''.join(lists2).upper()) #将要打印输出的字符进行大写

0x07.qwe密码
也叫键盘密码。
python实现:
`class QWECode(): #加密字典
qwe_table = {
'q': 'a', 'w': 'b', 'e': 'c', 'r': 'd', 't': 'e', 'y': 'f', 'u': 'g',
'i': 'h', 'o': 'i', 'p': 'j', 'a': 'k', 's': 'l', 'd': 'm', 'f': 'n',
'g': 'o', 'h': 'p', 'j': 'q', 'k': 'r', 'l': 's', 'z': 't',
'x': 'u', 'c': 'v', 'v': 'w', 'b': 'x', 'n': 'y', 'm': 'z',

'Q': 'A', 'W': 'B', 'E': 'C', 'R': 'D', 'T': 'E', 'Y': 'F', 'U': 'G',
'I': 'H', 'O': 'I', 'P': 'J', 'A': 'K', 'S': 'L', 'D': 'M', 'F': 'N',
'G': 'O', 'H': 'P', 'J': 'Q', 'K': 'R', 'L': 'S', 'Z': 'T',
'X': 'U', 'C': 'V', 'V': 'W', 'B': 'X', 'N': 'Y', 'M': 'Z',
}
decode_table = dict([val,key] for key,val in qwe_table.items())     #解密对照表
def encode(self,plaitext):  #定义加密方法
    charlist = list(plaitext.upper())   #定义一个列表,并将其中的字小写字母化为大写
    qwecodelist = 
        [self.qwe_table[char]  if char in self.qwe_table.keys() else '' for char in charlist] #通过对比字典的键值对,得到相应得值并将其写入列表里
    return " ".join(qwecodelist)   #返回qwecodelist里的数据
def decode(self,qwecode):          #定义解密方法  
    qwecodelist = qwecode.split(" ")      #使用split分割函数对输入的进行分割
    charlist = 
        [self.decode_table[char] if char in self.decode_table.keys() else '' for char in qwecodelist] #通过对比字典的键值对,得到相应得值并将其写入列表里
    return " ".join(charlist)   #返回charlist里的数据

if name == 'main':#调试该模块的正确性,执行当前模块
m = QWECode() #定义一个变量m
plaitext = input('输入:') #输入需要加密的内容
qwecode = m.encode(plaitext) #调用encode加密方法
print("加密结果为:",qwecode) #输出打印加密的结果

if name == 'main':#调试该模块的正确性,执行当前模块

#m = QWECode()  #定义一个变量m
#plaitext = input('输入:') #输入需要解密的内容
#qwecode = m.encode(plaitext)  #调用decode解密方法
#print("加密结果为:",qwecode)  #输出打印解密的结果`

0x08.engima加密
参考链接https://blog.csdn.net/chengqiuming/article/details/82078430

0x09.摩斯密码
尔斯电码(又译为摩斯密码,Morse code)是一种时通时断的信号代码,通过不同的排列顺序来表达不同的英文字母、数字和标点符号。不同于现代只使用零和一两种状态的二进制代码,它的代码包括五种: 点、划、点和划之间的停顿、每个词之间中等的停顿以及句子之间长的停顿。摩尔斯电码由两种基本信号组成:短促的点信号“·”,保持一定时间的长信号为“-”。
python实现:
`class MorseCode: #定义morescode这个类
encode_table = {"A": ".-", "B": "-...", "C": "-.-.", "D": "-..", # 加密对照表
"E": ".", "F": "..-.", "G": "--.", "H": "....",
"I": "..", "J": ".---", "K": "-.-", "L": ".-..",
"M": "--", "N": "-.", "O": "---", "P": ".--.",
"Q": "--.-", "R": ".-.", "S": "...", "T": "-",
"U": "..-", "V": "...-", "W": ".--", "X": "-..-",
"Y": "-.--", "Z": "--..",
"1": ".---", "2": "..---", "3": "...--", "4": "....-",
"5": ".....", "6": "-....", "7": "--...", "8": "---..",
"9": "----.", "0": "-----",
"(": ".--.-", "-": "-....-", "?": "..--..", "/": "-..-.",
".": ".-.-.-", "@": ".--.-."
}
decode_table = dict([val,key] for key,val in encode_table.items())#解密对照表
def encode(self,plaitext): #定义加密方法
charlist = list(plaitext.upper()) #定义一个列表,并将其中的字小写字母化为大写
morsecodelist =
[self.encode_table[char] if char in self.encode_table.keys() else '' for char in charlist] #通过对比字典的键值对,得到相应得值并将其写入列表里
return " ".join(morsecodelist) #返回morsecodelist里的数据
def decode(self,morsecode): #定义解密方法
morsecodelist = morsecode.split(" ") #使用split分割函数对输入的进行分割
charlist =
[self.decode_table[char] if char in self.decode_table.keys() else '' for char in morsecodelist] #通过对比字典的键值对,得到相应得值并将其写入列表里
return " ".join(charlist) #返回charlist里的数据
if name == 'main': #调试该模块的正确性,执行当前模块
m = MorseCode() #定义一个变量m
plaitext = input('输入:') #输入要加密的内容
morsecode = m.encode(plaitext) #调用写好的加密方法encode
print("加密结果为:",morsecode) #输出加密的结果

if name == 'main': #调试该模块的正确性,执行当前模块

m = MorseCode() #定义一个变量m

plaitext = input('输入:') #输入需要解密的内容

morsecode = m.decode(plaitext) #调用解密方法decode

print("解密结果为:",morsecode #输出解密的结果`

0x10.跳舞的小人
跳舞的小人是出自于福尔摩斯探案集。1898年歇洛克·福尔摩斯接受了希尔顿·丘比特的调查邀请,1897年丘比特先生和夫人埃尔西·丘比特在伦敦相爱并结婚,但是在1898年的六月底,埃尔西突然接到一封来自美国的信件之后,便显得些不安。在此之后一个多月丘比特家中开始出现跳舞的小人,为了弄清楚其中的含义,丘比特先生便请求福尔摩斯解读这些暗号。
此处会用到频率分析法:
频率分析法:将明文字母出现的频率与密文字母的频率相比较的过程,通过分析每个符号出现的频率而轻易地破译代换式密码。在每种语言中,冗长的文章中的字母表现出一种可对之进行分辨的频率。简单的说就是将明文的出现频率与
密文字母的频率相比较,从而实现破解密码的一种方法。

欢迎一起交流。
原文地址:https://www.cnblogs.com/huazige/p/14053224.html