将字符串解密为数字

时间:2016-02-03 20:54:31

标签: python python-3.x encryption

上周,我被指派将数字PIN加密成可发音的字符串(由元音辅音对组成)。这很顺利。

本周,我被分配到解密我的函数生成的字符串回到原来的PIN表格中。我试图对我的代码进行反向工程,但我不知道从哪里开始。

全局变量:

CONSONANTS = "bcdfghjklmnpqrstvwyz" 
VOWELS = "aeiou" 

加密代码:

def alphapinEncode(pin):
    '''(num) -> string
    Takes user input (pin) and converts it into a pronounceable string.
    Returns the string (codedPin)

    Examples:
    >>> alphainEncode(4327)
    'lohi'
    >>> alphainEncode(3463470)
    'bomejusa'
    '''

    codedPin = ""

    while pin > 0:
        last_two_digits = pin % 100
        codedPin = VOWELS[last_two_digits % 5] + codedPin
        codedPin = CONSONANTS[last_two_digits // 5] + codedPin
        pin = pin // 100

    return codedPin

解密代码:

def alphapinDecode(codedPin):
    '''(string) -> num
    DOCSTRING PLACEHOLDER
    '''

    #This while loop checks validity of input string (string).
    testPin = codedPin
    while len(testPin) > 0:
        if testPin[-1] in VOWELS and testPin[-2] in CONSONANTS:
            testPin = testPin[:-2]
        else:
            print ("Your string is incorrectly formatted. Please use consonant-vowel pairs.")
            return None

    #Decryption code goes here!

    return #pin

2 个答案:

答案 0 :(得分:5)

您的规范问题:当要解码的字符串长度不均匀时会发生什么?

忽略这种情况,你的方法应该类似于:

  1. codedPin拆分为2个组,或者从输入中一次取2个字符。保留这些值,以便我们可以解码当前的2组。

  2. 反转用于加密引脚的算法。许多评论都说你不能反转模运算 - 这在通用情况下可能是正确的,但由于我们只处理正整数,我们当然可以扭转价值。这里有一个提示:找到原始indexCONSONANTS字符串中每个字符的VOWELS,为自己提供一个数字。如果您遇到数学问题,请尝试手动解码一张纸上的一个示例。密切注意字符索引与原始PIN码之间的关系。

  3. 存储每对数字的值,直到到达字符串的末尾。

  4. 返回或输出完整值。

  5. 我不会为你编写答案,因为我相信你最好自己想出一些东西。将这些步骤作为指针并开始编码!看看你提出了什么并回来,你会得到一些代码,你可以用来提出实际问题。

答案 1 :(得分:1)

这是一个有趣的问题。我认为这有效:

pin = 123456789
c = alphapinEncode(pin)
c
'begomariwu'

sum([n*100**(len(c)/2-i-1) for i,n in enumerate([CONSONANTS.index(p[0])*5 + VOWELS.index(p[1]) for p in [c[i:i+2] for i in range(0, len(c), 2)]])])
123456789

或者,感谢@mata建议使用reduce,这个改进的单行版本:

reduce(lambda a,b:100*a + b, [CONSONANTS.index(consonant)*5 + VOWELS.index(vowel) for consonant, vowel in [c[i:i+2] for i in range(0, len(c), 2)]], 0)

现在要认真对待。单行可以制作有趣的谜题,但真正的代码应该是可读的。这是我的真实答案:

def alphapinDecode(codedPin):
    pin = 0
    pairs = [codedPin[i:i+2] for i in range(0, len(codedPin), 2)]

    for consonant, vowel in pairs:
        pin = pin*100 + CONSONANTS.index(consonant)*5 + VOWELS.index(vowel)

    return pin

我认为没有评论就相当清楚。与往常一样,好的变量名称有很多帮助。

您对alphapinEncode的实现很好,但我仍然主要用样式更改重写它,还要使用divmod:

def alphapinEncode(pin):
    codedPin = ''

    while 0 < pin:
        pin, current_digits = divmod(pin, 100)
        codedPin = (
            CONSONANTS[current_digits // 5] +
            VOWELS[current_digits % 5] +
            codedPin
        )

    return codedPin