上周,我被指派将数字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
答案 0 :(得分:5)
您的规范问题:当要解码的字符串长度不均匀时会发生什么?
忽略这种情况,你的方法应该类似于:
将codedPin
拆分为2个组,或者从输入中一次取2个字符。保留这些值,以便我们可以解码当前的2组。
反转用于加密引脚的算法。许多评论都说你不能反转模运算 - 这在通用情况下可能是正确的,但由于我们只处理正整数,我们当然可以扭转价值。这里有一个提示:找到原始index
和CONSONANTS
字符串中每个字符的VOWELS
,为自己提供一个数字。如果您遇到数学问题,请尝试手动解码一张纸上的一个示例。密切注意字符索引与原始PIN码之间的关系。
存储每对数字的值,直到到达字符串的末尾。
返回或输出完整值。
我不会为你编写答案,因为我相信你最好自己想出一些东西。将这些步骤作为指针并开始编码!看看你提出了什么并回来,你会得到一些代码,你可以用来提出实际问题。
答案 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