栅栏密码&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))


posted @ 2020-10-09 17:16  lnjoy  阅读(7943)  评论(0编辑  收藏  举报