各位白嫖…漂亮大哥哥姐姐们好,在下菜鸡一枚,主要想在这和大家一起探讨学习之道,一起愉快的学习密码学基础。总所周知,密码学学的好,头发掉的少。。。
直接进入正题,今天我就主要讲三个密码,而且都是古典密码,而且都比较简单:
他们是:凯撒密码,Play fair密码,维吉尼亚密码
不多说,先来凯撒:
咱先来加密:
C=[chr((ord(x.lower())-ord('a')+3)%26+ord('a')) for x in m if x.lower() in "abcdefghijklmnopqrstuvwxyz"]
???结束了??这可能是个意外,咱再来看看解密:
m=[chr((ord(x.lower())-ord('a')-3)%26+ord('a')) for x in C if x.lower() in "abcdefghijklmnopqrstuvwxyz"]
???兄弟呀,这就没意思了,男人不能这么快的!!!
(我觉得你在开车,但是我没有证据)
凯撒密码属于移位密码,移位的操作就是很简单的加三,所以,快是很正常的,毕竟对吧
凯撒密码这种垃圾东西,我都不在乎,垃圾东西。
别别别,大帝,我不是这个意思!
介绍完凯撒大帝,哦不,密码,咱们来看一下Playfair密码:
首先,我们要介绍一些前提:
print(“playfair 密码是一种古典多表代换密码”)
print(“指定字符,z”)
print(“预处理,1.Key变成矩阵”)
print(“5*5矩阵,i,j看作一个字符,字母只出现一次,密钥去重,按原有顺序排列,字母表掏空密钥字符,按原有加入排列”)
print(“明文两两结合,分开成为数组,以待加密”)
print(“加密规则:”)
print(“1.p1,p2同行,密文为其右边字符,每行首尾视作相连”)
print(“2.p1,p2同列,密文为其下边字符,每列首尾视作相连”)
print(“3.p1,p2相同,不做改变”)
print(“4.明文长度为奇数,加z变为偶数”)
print(“5.p1,p2不同行,列,p1,p2为顶点矩形字母,同行互换”)
class pfcode:
def __init__(self):
print("playfair 密码是一种古典多表代换密码")
print("指定字符,z")
def CreateKey(self,key):
arr=''
for i in key:
if i=='j':
i='i'
if i not in arr:
arr+=i
arr_a=[x for x in 'abcdefghiklmnopqrstuvwxyz']
for i in arr:
if i in arr_a:
arr_a.remove(i)
key_str=arr+''.join(arr_a)
self.keys={key_str[x]:((int)(x/5),x%5) for x in range(0,len(key_str))}
#print(self.keys)
def CreateMw(self,M):
if len(M)%2!=0:
M+='z'
return [M[i:i+2] for i in range(0,len(M),2)]
def Trans(self,x):
def get(value):
for i in self.keys.keys():
if self.keys[i]==value:
return i
p1=self.keys[x[0]]
p2=self.keys[x[1]]
if x[0]==x[1]:
return x[0]+x[1]
if p1[0]==p2[0]:
return get((p1[0],(p1[1]+1)%5))+get((p2[0],(p2[1]+1)%5))
elif p1[1]==p2[1]:
return get(((p1[0]+1)%5,p1[1]))+get(((p2[0]+1)%5,p2[1]))
else:
return get((p1[0],p2[1]))+get((p2[0],p1[1]))
def Rtrans(self,x):
def get(value):
for i in self.keys.keys():
if self.keys[i]==value:
return i
p1=self.keys[x[0]]
p2=self.keys[x[1]]
if x[0]==x[1]:
return x[0]+x[1]
if p1[0]==p2[0]:
return get((p1[0],(p1[1]-1)%5))+get((p2[0],(p2[1]-1)%5))
elif p1[1]==p2[1]:
return get(((p1[0]-1)%5,p1[1]))+get(((p2[0]-1)%5,p2[1]))
else:
return get((p1[0],p2[1]))+get((p2[0],p1[1]))
def Encode(self,M,Key):
M=[x.lower() for x in M if x.lower() in "abcdefghiklmnopqrstuvwxyz"]
Key=[x.lower() for x in Key if x.lower() in "abcdefghiklmnopqrstuvwxyz"]
self.CreateKey(Key)
mw=self.CreateMw(M)
C=[self.Trans(x) for x in mw]
return ''.join(C)
def Decode(self,C,Key):
C=[x.lower() for x in C if x.lower() in "abcdefghiklmnopqrstuvwxyz"]
Key=[x.lower() for x in Key if x.lower() in "abcdefghiklmnopqrstuvwxyz"]
self.CreateKey(Key)
c=self.CreateMw(C)
mw=[self.Rtrans(x) for x in c]
return ''.join(mw)
def Show(self):
print("预处理,1.Key变成矩阵")
print("5*5矩阵,i,j看作一个字符,字母只出现一次,密钥去重,按原有顺序排列,字母表掏空密钥字符,按原有加入排列")
print("明文两两结合,分开成为数组,以待加密")
print("加密规则:")
print("1.p1,p2同行,密文为其右边字符,每行首尾视作相连")
print("2.p1,p2同列,密文为其下边字符,每列首尾视作相连")
print("3.p1,p2相同,不做改变")
print("4.明文长度为奇数,加z变为偶数")
print("5.p1,p2不同行,列,p1,p2为顶点矩形字母,同行互换")
我自认为这算是比较精简的了,(狗头保命)
解释一下,我的矩阵是个什么样子的:
‘字符’:(i,j) 这就是我的矩阵元素,位置有了,字符有了,还方便查询取出,不愧是我,我真聪明。
关于维多利亚这一款密码,我是很懂。。。的。。。
咳咳,顿时社会主义新青年的热血涌上心头,毛主席的教导,辅导员的关爱,老父老母的热泪盈眶的画面顿时在脑海中闪现,吓得我赶紧关掉电脑,回家打了把LOL(王者)、喝了口茶,跑了五千米,然后再次打开电脑,搜索:
老爸缓缓拿起来手中的狼牙棒,老妈也缓缓举起手中的菜刀,爸欸,爸,听我解释,。。。。
#author:dager
#time:2020/9/10
#description:维吉尼亚密码
class vjnycode:
def __init__(self):
print("维吉尼亚密码,这是一种古典密码!!!")
def Encode(self,m,key):
m=''.join([x.lower() for x in m if x.lower() in "abcdefghijklmnopqrstuvwxyz"])
key=''.join([x.lower() for x in key if x.lower() in "abcdefghijklmnopqrstuvwxyz"])
m_len,k_len=len(m),len(key)
if m_len<k_len:
print("兄嘚,你是不是密码密钥弄反了?")
else:
keys=key*(int)(m_len/k_len)+key[0:(m_len%k_len)]
C=[chr((ord(m[x])-2*ord('a')+ord(keys[x]))%26+ord('a')) for x in range(0,len(m))]
return ''.join(C)
def Decode(self,C,key):
C=''.join([x.lower() for x in C if x.lower() in "abcdefghijklmnopqrstuvwxyz"])
key=''.join([x.lower() for x in key if x.lower() in "abcdefghijklmnopqrstuvwxyz"])
c_len,k_len=len(C),len(key)
if c_len<k_len:
print("兄嘚,你是不是密码密钥弄反了?")
else:
keys=key*(int)(c_len/k_len)+key[0:(c_len%k_len)]
m=[chr((ord(C[x])-ord('a')-(ord(keys[x])-ord('a')))%26+ord('a')) for x in range(0,len(C))]
return ''.join(m)
def Show(self):
print("维吉尼亚密码,核心加密方法,(mi+ki)%26 =>Ci")
果然,我还是最棒的!!!老爸看完我的代码,欣慰的放下了手中断掉的狼牙棒,老妈也卖掉了手中卷刃的菜刀。又是一个和谐的一天!!!
这些都属于比较基础的古典密码,所以就把代码发一下,咱才不是混子呢!!哼。
最后,给大家介绍一下莫斯密码:请听好:
荣耀下播,起飞!!!!