1. 程式人生 > 實用技巧 >古典密碼學教學

古典密碼學教學

一.目錄
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解密\n") #此處進行一個加密/解密的選擇,使用if語句
if choose == 'E': #輸入E進行加密運算
s1=input('輸入需要加密的內容: \n') #輸入需要加密的內容

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('輸入要解密的內容:\n') #輸入需要解密的內容
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進行解密:\n") #進行選擇
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進行解密:\n") #進行選擇 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年的六月底,埃爾西突然接到一封來自美國的信件之後,便顯得些不安。在此之後一個多月丘位元家中開始出現跳舞的小人,為了弄清楚其中的含義,丘位元先生便請求福爾摩斯解讀這些暗號。
此處會用到頻率分析法:
頻率分析法:將明文字母出現的頻率與密文字母的頻率相比較的過程,通過分析每個符號出現的頻率而輕易地破譯代換式密碼。在每種語言中,冗長的文章中的字母表現出一種可對之進行分辨的頻率。簡單的說就是將明文的出現頻率與
密文字母的頻率相比較,從而實現破解密碼的一種方法。