0

我正在尝试解决一个问题,该问题涉及解码用多级凯撒密码编码的文本字符串。通过返回 Do 似乎适用于第一个班次,但它不会递归。我在整个过程中都有打印语句,显示了我正在使用的片段并将其放入函数中,它们似乎是正确的。

def build_decoder(shift):
    cipher = build_coder(shift)
    decoder = {}
    for k, v in cipher.items():
        decoder[v] = k
    return decoder

def is_word(wordlist, word):
    word = word.lower()
    word = word.strip(" !@#$%^&*()-_+={}[]|\:;'<>?,./\"")
    return word in wordlist

def apply_coder(text, coder):
    encrypted = []
    for character in text:
        if character in coder.keys():
            encrypted.append(coder[character])
        else:
            encrypted.append(character)
    return ''.join(encrypted)

def apply_shift(text, shift):
    coder = build_coder(shift)
    return apply_coder(text, coder)

def apply_shifts(text, shifts):
    for index, shift in shifts:
        text = (text[:index]) + (apply_coder(text[index:], build_coder(shift)))
    return text

def find_best_shifts_rec(wordlist, text, start=0):
            """
            text: scrambled text to try to find the words for
            start: where to start looking at shifts
            returns: list of tuples.  each tuple is (position in text, amount of shift)
            """
            key = []
            for shift in range(28):
                message = text[:start] + apply_shift(text[start:], -shift) #Concatenate text from beginning to start with an apply_shift from start to end of text.
                space = message[start:].find(" ") #Find next space from start to " " character.
                if is_word(wordlist, message[start:space]): #If text from start to space is a word.
                    print message[start:space]
                    key.append((start, shift)) #Add position and shift as tuple in list key.
                    print key
                    print len(message[:start]), message[:start]
                    print len(message[start:space]), message[start:space]
                    print len(message), message
                    print message[:space]
                    print message[space+1:]
                    print message[space+1]
                    if not(is_word(wordlist, message[start:])):
                        return message[:space] + find_best_shifts_rec(wordlist, message, space+1) #Return text from beginning to space(decrypted) and recursively call find_best_shifts_rec on rest of text.
                    else:
                        return message[start:]
            print "No shift match found, closest match:"
            print key
            return ''

s = apply_shifts("Do Androids Dream of Electric Sheep?", [(0,6), (3, 18), (12, 16)])
print find_best_shifts_rec(wordlist, s)

输出:

Do
[(0, 6)]
0 
2 Do
36 Do Sevif vjrKylhtgvmgLslj ypjgZollw?
Do
Sevif vjrKylhtgvmgLslj ypjgZollw?
S
No shift match found, closest match:
[]
Do
4

2 回答 2

0

我很确定这些行不会做你打算做的事情:

space = message[start:].find(" ")
if is_word(wordlist, message[start:space]):

space是 slice 中第一个空间的索引message[start:],但您将它用作整个消息的索引。为了您以后的切片工作,它应该是message[start:start+space]. 您在后面的代码中使用的其他地方也space应该是start+space.

现在,这可能不是唯一的错误,但这是我看到的第一个明显的错误。我实际上无法运行您的代码来测试其他错误,因为您没有提供build_coder由其他东西调用的函数(也没有 a wordlist,谁知道还有什么)。

于 2016-05-17T03:52:13.693 回答
0

我认为这是针对 MIT 6.00 课程的?我写了一个工作 find_best_shifts 和 find_best_shifts_rec。这是我的第一次编码经验,所以我确信我的代码可以改进,但它确实有效,所以你可以将它用作改进的基准。

def find_best_shifts(wordlist, text): 全局移位 shifts = [] return find_best_shifts_rec(wordlist, text, 0)

def find_best_shifts_rec(wordlist, text, start):

for shift in range(28):
        decoded = apply_shift(text[start:], shift)
        words = decoded.split()
        decoded = text[:start] + decoded
        string_split = decoded.split()
        size = len(string_split)
        correct_words = 0
        if is_word(wordlist, words[0]):
            if shift != 0:
                shifts.append((start,shift))
                new_start = start + len(words[0]) + 1
                if new_start >= len(text)-1:
                       return shifts
                else:
                    return find_best_shifts_rec(wordlist, decoded, start=new_start)
        for j in string_split:
            if is_word(wordlist, j):
                correct_words += 1
                if correct_words == size:
                    return shifts
于 2016-05-17T02:54:31.013 回答