解密Python字解码器

时间:2009-10-28 15:22:16

标签: python

我正在尝试深入研究python,我发现了(hackthissite.org)我正试图破解的挑战。我必须解读在提供的词表中找到的10个单词。

def permutation(s):
    if s == "":
        return [s]
    else:
        ans = []
        for an in permutation(s[1:]):
            for pos in range(len(an)+1):
                ans.append(an[:pos]+s[0]+an[pos:])
        return ans

def dictionary(wordlist):
    dict = {}
    infile = open(wordlist, "r")
    for line in infile:
        word = line.split("\n")[0]
        # all words in lower case!!!
        word = word.lower()
        dict[word] = 1
    infile.close()
    return dict

def main():
    diction = dictionary("wordlist.txt")
    # enter all the words that fit on a line or limit the number
    anagram = raw_input("Please enter space separated words you need to unscramble: ")
    wordLst = anagram.split(None)

    for word in wordLst:
        anaLst = permutation(word)
        for ana in anaLst:
            if diction.has_key(ana):
                diction[ana] = word
                #print "The solution to the jumble is" , ana
    solutionLst = []
    for k, v in diction.iteritems():
        if v != 1:
            solutionLst.append(k)
            print "%s unscrambled = %s" % (v, k)
    print solutionLst

main()

函数置换看起来像是实际进行解密的代码块。你能帮我理解它是如何以编程方式解决这个问题的吗?

3 个答案:

答案 0 :(得分:3)

伪代码看起来像:

Load the word list (dictionary)
Input the words to unscramble
For each word:
  Find every permutation of letters in that word (permutation)
  For each permutation:
    Add this permutation to the solution list if it exists in the dictionary
Print the solutions that were found.

dictionary()函数从文件中填充单词列表。

permutation()函数返回给定单词中每个字母的排列。


permutation()函数正在执行以下操作:

for an in permutation(s[1:]):

s [1:]返回截断第一个字符的字符串。您将看到它使用递归再次调用permutation(),直到没有任何字符从前面被截断。你必须知道递归才能理解这一行。使用递归可以使这个算法覆盖每个字母数,并且仍然很优雅。

for pos in range(len(an)+1):

对于剩余的每个字母位置。

ans.append(an[:pos]+s[0]+an[pos:])

通过将第一个字母(我们之前截断的)移动到每个其他字母之间的每个位置来生成排列。


因此,以“观察”这个词为例。递归后,会有一个循环生成以下单词:

awtch atwch atcwh atchw

我所做的只是生成这些单词的第一个字母并转移其位置。继续这一点,结合截断字母,你将创建每个排列。

(哇,这一定是我最长的答案)

答案 1 :(得分:1)

我也为该网站编写了此代码。 下面的工作代码:

def import_dictionary():
    dictionary = []
    try:
        file = open("C:\\Users\\Mason\\Desktop\\diction.txt", "r")#location of your dictionary or provided wordlist
        fileContents = file.readlines() #read text file and store each new line as a string
    finally:
        file.close()
    for i in range(len(fileContents)):
        dictionary.extend(fileContents[i].split()) #changes the list by removing \n's from line breaks in text file
    return dictionary

def import_scrambled_words():
    scrambledWords = []
    try:
        file = open("C:\\Users\\Mason\\Desktop\\scrambled.txt", "r") #location of your scrambled word file
        fileContents = file.readlines() #read text file and store each new line as a string
    finally:
        file.close()
    for i in range(len(fileContents)):
        scrambledWords.extend(fileContents[i].split()) #changes the list by removing \n's from line breaks in text file
    return scrambledWords

def unscramble_word(scrambledWord):
    countToMatch = len(scrambledWord)
    matchedWords = []
    string = ""

    for word in dictionary:
        count = 0
        for x in scrambledWord:
            if x in word:
                count += 1
            if count == countToMatch:
                matchedWords.append(word)
                break
    for matchedWord in matchedWords:
        if len(matchedWord) == len(scrambledWord):
            print(matchedWord)
            string = matchedWord
            break #this returns only one unscrambles word
    return string

if __name__ == '__main__':
    finalString = ""
    try:
        scrambled = import_scrambled_words()
        print(scrambled)
        dictionary = import_dictionary()
        for x in scrambled:
            finalString += unscramble_word(x)
            finalString +=", "
        len(finalString)

        print(finalString)

    except Exception as e:
        print(e)

此代码将从已保存的混乱单词文件中读取,并根据单词列表进行检查(在我的情况下,我使用字典只是为了额外)。为了在分配的30秒内击败挑战,我从hackThissite上复制粘贴并粘贴到我的乱码文件中。保存。运行程序并复制粘贴我的python控制台的输出。

答案 2 :(得分:0)

有一个更好的解决方案。如果有很多长字,这段代码效率很低。一个更好的想法是按字典顺序对字典中的每个单词进行排序,这样“上帝”变成了“dgo”,并且对于混乱的单词也是如此。然后是每个单词的O(nlogn)而不是O(n!)