柵欄密碼&W型柵欄密碼-加解密(python實現)


柵欄密碼

柵欄密碼定義如下:

柵欄密碼是將明文分成多個組,取每組第一個字符連成一段,每組第二個字符連成一段……最后將各段連接起來得到密文。

同時也可看成是按一定的步長取幾組字符,再將這幾組字符連起來得到密文。解密同理。

這里的步長就是密鑰(欄數)。

傳統柵欄密碼的密鑰是密文長度的因數。

如密文長度為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))



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM