CTF 栅栏加密解密----python代码实现
目錄
文章目錄
前言
一、柵欄密碼是什么?
二、使用步驟
1.加密過程理解+實現
2.解密過程理解+實現
3.解密過程問題:
總結
前言
最近在學習CTF的密碼題目,邊做題,邊學習用python實現。
提示:全文的明文為IAMMANBUTLIKEWOMEN
在線柵欄密碼加密解密,推薦使用這個在線工具,ctf在線工具庫里面的,好像有問題。
https://www.qqxiuzi.cn/bianma/zhalanmima.php
一、柵欄密碼是什么?
所謂柵欄密碼,就是把要加密的明文分成N個一組,然后把每組的第1個字連起來,形成一段無規律的話。 不過柵欄密碼本身有一個潛規則,就是組成柵欄的字母一般不會太多。(一般不超過30個,也就是一、兩句話) from 百度百科
二、使用步驟
1.加密過程理解+實現
明文為IAMMANBUTLIKEWOMEN????? ;加密密鑰為3
加密陣列見表
| m\n | 0列 | 1列 | 2列 |
| 分組0 | I?? (0) | A?? (1) | M?? (2) |
| 分組1 | M?? (3) | A?? (4) | N?? (5) |
| 分組2 | B?? (6) | U?? (7) | T?? (8) |
| 分組3 | L?? (9) | I?? (10) | K?? (11) |
| 分組4 | E?? (12) | W?? (13) | O?? (14) |
| 分組5 | M?? (15) | E?? (16) | N?? (17) |
則:密文為IMBLEM?? AAUIWE?? MNTKON
解讀:將一段字符串(明文)按照(加密密鑰)3個一組進行排列,然后將每組的第一列提取,第二列,第三列。分別循環提取。
第0列,下標依次是(0、3、6、9、12、15) ?????? +0
第1列,下標依次是(1、4、7、10、13、16)看作(0、3、6、9、12、15)+1??
第2列,下標依次是(2、5、8、11、14、17)看作(0、3、6、9、12、15)+2
小結:在加密過程中,每次提取string_C明文串中 下標為 [m*Ek+n] 的字符
m為?? 加密過程中得 第m分組?
取值為0,1,2, ……,len(string_C)/Ek -1
(上例明文長度為18,加密密鑰為3,則相除? 得6;m=0,1,2,3,4,5)?
注意,當 明文長度 不能被? 密鑰? 整除時,會多出一個分組。
如果長度為18 ,密鑰為5,相除得3.6。
這時m得取值為0,1,2, ……,int(len(string_C)/Ek)
但在代碼實現過程中,不需要特別區分。 m < len(string_C)/Ek?? 即可
n為? 加密過程中,第n列字符,取值為0,1,2, …… ,Ek-1?? (上例n=? 0,1,2)
n < Ek
加密函數:
def fun_enCrypto(string_C , Ek):string_M = '' #初始化密文n = 0 #提取第n列字符while n < Ek:m = 0 #第m分組while m < len(string_C) / Ek: #明文長度/加密密鑰 即得分組個數if (m * Ek+ n) < len(string_C):string_M = string_M + string_C[int(m * Ek+ n)]m += 1else :breakn += 1return string_M2.解密過程理解+實現
密文為IMBLEMAAUIWEMNTKON
加密密鑰為3
求明文,解密密鑰為Dk=len(string_M)/Ek? 為18/3=6
按照解密規則,得出如下過程。
| m\n | 0列 | 1列 | 2列 | 3列 | 4列 | 5列 |
| 分組0 | I(0) | M(1) | B(2) | L(3) | E(4) | M(5) |
| 分組1 | A(6) | A(7) | U(8) | I(9) | W(10) | E(11) |
| 分組2 | M(12) | N(13) | T(14) | K(15) | O(16) | N(17) |
明文:IAM MAN BUT LIK EWO MEN
解讀:將一段字符串(密文)按照6(解密密鑰)個一組進行排列,然后將每組的第一列提取,第二列,第三列,第四列,第五列,第六列。分別循環提取。
0列,第一列下標依次是(0、6、12) ?????? +0
1列,第二列下標依次是(1、7、13)看作(0、6、12)+1??
*
n列,第n+1列下標依次是(0*Dk+n,1*Dk+n,2*Dk+n)
*
5列,第六列下標依次是(5、11、17)看作(0、6、12)+5
小結:在解密過程中,每次提取string_M密文串中 下標為 [m*Dk+n] 的字符
m為?? 解密過程中得 第m分組?
取值為0,1,2, ……,len(string_M)/Dk -1
(在上例中18/6=3;m=0,1,2);Dk由len(string_M)/Ek得到。
解密過程代碼實現:
n = 0while n < Dk:m = 0while m < Ek:if (m * Dk + n) < len(string_M):string_C = string_C + string_M[int(m * Dk + n)]m += 1else:breakn += 1return string_C3.解密過程問題:
用上述代碼實現解密的時候,運行程序時,發生問題:
如:已知字符串長度為18,當Ek=5時,解密得到明文就不是我們希望得到的明文。發現,當len(string_M)% Ek != 0 時,上述過程返回明文字符串不正確。
結論:再代碼實現時,需判斷? len(string_M)% Ek?? 是否? 等于? 0
我們對一個余數≠0的實例進行解讀:(加密密鑰Ek為5;密文:INIMABKEMUENMTWALO)
解密陣列:INIMABKEMUENMTWALO
求明文,解密密鑰為Dk=len(string_M)/Ek? 為18=Ek*3+3???? (18/15=3.5)
| 0列 | 1列 | 2列 | 3列 | |
| 分組0 | I(0) | N(1) | I(2) | M(3) |
| 分組1 | A(4) | B(5) | K(6) | E(7) |
| 分組2 | M(8) | U(9) | E(10) | N(11) |
| 分組3 | M(12) | T(13) | W(14) | |
| 分組4 | A(15) | L(16) | O(17) |
通過觀察解密陣列,無法通過m\n進行提取字符。
?這里引入一個概念:步長數組。即解密過程中下一個字符到上一個字符的下標之差組合成一個數組,上例中,步長數組位[4,4,4,3,3] 。數組元素個數為Ek(加密密鑰)
1.若len(M)%Ek==0時,Dk=len(M)/Ek,步長=Dk。 2.若len(M)%Ek≠0 時,則步長存在大步長=int(Dk)+1和小布長Dk。相差1. 大步長的個數為 len(M)%Ek 余數。 小布長的個數為 Ek-len(M)%Ek #Rail-Fence Cipher柵欄解密,輸入加密分組中每組中的字符個數 def fun_deCrypto(string_M, Ek):Dk = int(len(string_M) / Ek)string_C = ''yushu = len(string_M) % Eksteps = []if len(string_M) % Ek == 0:print('不存在余數')step = Dkfor i in range(Ek):steps.append(step)print(steps)else:print('存在余數')big_step = math.ceil(len(string_M) / Ek)small_step = int(len(string_M) / Ek)for p in range(yushu):steps.append(big_step)for q in range(Ek - yushu):steps.append(small_step)print(steps)n_column = 0while n_column < math.ceil(len(string_M) / Ek):count_steps = 0for one_step in steps:if len(string_C) == len(string_M):breakelse:string_C += string_M[n_column + count_steps]count_steps += one_stepn_column += 1return string_C總結
柵欄加密解密,即將一個字符串。按照一定的間隔提取單個字符,再按照提取的先后順序,重組成一個字符串。
加解密都可以通過步長數組實現。如果步長數組為[2,2,1,1],首先提取起始0位,走2步,到第2位,再走2步,到第4位,再走1步到第5位。起始位+1,提取第1位,再走2步,到第3位。
?
?
?
總結
以上是生活随笔為你收集整理的CTF 栅栏加密解密----python代码实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python实现动态壁纸_Python
- 下一篇: macOS Monterey下找到桌面图