无法为我的加密编码解密

时间:2015-01-29 20:00:43

标签: python cryptography

我必须为Python问题进行加密。

def encrypt(n,string):
    #get length of string
    length = len(string)

    #traverse string and move text to newStringList
    newStringList = []
    for i in range(0,length,n):
        newStringList.append(string[i:i+n])
    #endfor

    #add to orderedList
    o = len(newStringList)
    orderedList = []

    for i in range(n):
        for j in range(o):
            if j<len(newStringList) and i<len(newStringList[j]):
                orderedList.append(newStringList[j][i])
        #endfor
    #endfor

    #join list into string
    encrypted = "".join(orderedList)
    print(encrypted)
#end def

这样可以使字符串成为n列的表。然后通过逐列读取列来生成加密的字符串。我的问题涉及解密。

如果我使用完全相同的代码进行解密,则仅在len(string)%n == 0时才有效。例如,如果我输入decrypt(3,"147258369"),则会打印123456789,但如果我输入decrypt(3,"1470258369"),则应打印1234567890,但会打印1089423756。我花了很多年时间试图解密,但我无法做到正确,请帮助我 的修改
不幸的是,我测试了一个巧合而不是方法的数字,它在len(string)%n == 0时并不总是有效。任何人都可以提供替代解决方案我的加密代码按我的意愿工作,但我无法弄清楚如何编写成功的解密代码。 的添加 只使用基本测试和循环的解决方案将非常受欢迎,类似于我的加密。

2 个答案:

答案 0 :(得分:1)

使用ord的简单解决方案:

def encrypt(n, string):
    return "".join(chr(ord(ch) + n * n) for ch in string)


def decrypt(n, string):
    return "".join(chr(ord(ch) - n * n) for ch in string)

In [14]: e = encrypt(3, "123456789")

In [15]: e
Out[15]: ':;<=>?@AB'

In [16]: decrypt(3, e)
Out[16]: '123456789'

要加密,我们只需使用ord添加每个char + n * n的ord来更改字符,然后简单地解密 - n * n。

答案 1 :(得分:0)

嗯,虽然它没有为您提供完全对话的加密功能,但这仍有效:

from itertools import zip_longest

def encrypt_chunker(it, n):
    for i in range(0, len(it), n):
        yield it[i:i+n]

def decrypt_chunker(it, n, overflow):
    i = 0
    base_width = len(it) // n
    while i < len(it):
        if overflow:
            width = base_width + 1
            overflow -= 1
        else:
            width = base_width
        yield it[i:i+width]
        i += width

def crypt(string, n, mode):
    if mode == 'encrypt':
        chunks = encrypt_chunker(string, n)
    elif mode == 'decrypt':
        overflow = len(string) % n
        chunks = decrypt_chunker(string, n, overflow)
    thing = zip_longest(*chunks)
    crypted = ''.join(''.join(c for c in tup if c) for tup in thing)
    return crypted

观察:

>>> crypt('1234567890', 3, 'encrypt')
'1470258369'
>>> crypt(_, 3, 'decrypt')
'1234567890'
>>> s = '1234567890'; n = 3; assert crypt(crypt(s, n, 'encrypt'), n, 'decrypt') == s # no AssertionError

crypt(string, n, 'encrypt')与您的encrypt(n, string)相同(已在大量随机字符串和值n上验证)。要获得对合,您必须执行crypt(crypt(string, n, 'encrypt'), n, 'decrypt')之类的操作。

我不认为它可以像您描述的那样拥有完全对话的加密功能 - 当您执行加密时(特别是&的位置),您将丢弃信息#34; blanks&#34;在你最里面的循环中)。这就是为什么你必须添加一点信息 - 无论你是加密还是解密。这允许您确定将字符串分块的正确方法。