柵欄密碼
柵欄密碼定義如下:
柵欄密碼是將明文分成多個組,取每組第一個字符連成一段,每組第二個字符連成一段……最后將各段連接起來得到密文。
同時也可看成是按一定的步長取幾組字符,再將這幾組字符連起來得到密文。解密同理。
這里的步長就是密鑰(欄數)。
傳統柵欄密碼的密鑰是密文長度的因數。
如密文長度為n,加密密鑰為x,則有n%x==0。且解密密鑰即為n/x。
代碼:
'''
遍歷所有可能的欄數,並得到加/解密結果
'''
s = 'KYsd3js2E{a2jda}'
factors = [fac for fac in range(2, len(s)) if len(s)%fac == 0] #取得密文長度的所有因數
for fac in factors:
flag = ''
for i in range(fac): #按一定的步長取幾組字符,並連接起來,這里組數就等於步長數
flag += s[i::fac]
print(str(fac)+'欄:'+flag)
W型柵欄密碼
W型柵欄密碼是柵欄密碼的變種,
將明文按w型排列,然后將每一行的字母依次連起來組成密文,行數就是密鑰。
解密則同樣畫出這個w型圖案,將每一列的字母依次連接起來組成明文。
W型柵欄密碼的密鑰不只是密文長度的因數,任何小於密文長度大於1的整數都有可能。
代碼:
'''
若知道欄數,則使用decode解密,若不知道,則使用crack_cipher遍歷所有可能性
'''
def generate_w(string, n):
'''將字符排列成w型'''
array = [['.']*len(string) for i in range(n)] #生成初始矩陣
row = 0
upflag = False
for col in range(len(string)): #在矩陣上按w型畫出string
array[row][col] = string[col]
if row == n-1:
upflag = True
if row == 0:
upflag = False
if upflag:
row -= 1
else:
row += 1
return array
def encode(string, n):
'''加密'''
array = generate_w(string, n)
msg = []
for row in range(n): #將每行的字符連起來
for col in range(len(string)):
if array[row][col] != '.':
msg.append(array[row][col])
return array, msg
def decode(string, n):
'''解密'''
array = generate_w(string, n)
sub = 0
for row in range(n): #將w型字符按行的順序依次替換為string
for col in range(len(string)):
if array[row][col] != '.':
array[row][col] = string[sub]
sub += 1
msg = []
for col in range(len(string)): #以列的順序依次連接各字符
for row in range(n):
if array[row][col] != '.':
msg.append(array[row][col])
return array, msg
def crack_cipher(string):
'''破解密碼'''
for n in range(2,len(string)): #遍歷所有可能的欄數
print(str(n)+'欄:'+''.join(decode(string, n)[1]))
if __name__ == "__main__":
string = "ccehgyaefnpeoobe{lcirg}epriec_ora_g"
n = 5 #欄數
#若不知道欄數,則遍歷所有可能
# crack_cipher(string)
#若知道欄數
array,msg = decode(string, n)
# array,msg = encode(string, n)
for i in array: print(i)
print(''.join(msg))