如何使用马尔可夫链得到所有的可能性?

2021-11-29 22:17:32 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图实现一个语言密码破解使用马尔可夫链。你知道吗

这背后的想法是从文本中选择n-gram,选择一个起始n-gram(通常是一个位于句首的单词),并使用前n-1个字符将其表示为一个状态。举个例子,对于“the”,我将有“th”。这将有一个字母及其出现的列表,并将表示为一个字典。dict["th"] = [('e', 120), ('a', 79)]等。 对于这些值中的每一个,我将尝试创建一个满足我的密码或密码长度的马尔可夫链。这意味着,当马尔可夫链的长度与我要查找的密码相同时,我将停止执行并检查马尔可夫链是否与我的密码相同。我试图实现这一点,使用递归函数,但由于某种原因,我得到堆栈溢出。你知道吗

def ceva(myTry, good_all, pwd, guess, level):
        save = myTry
        if len(pwd) == len(guess):
            if pwd == guess:
                return 1
        else:
            if myTry in good_all.keys():
                values = good_all[myTry]
                for i in range(0,len(values)):
                    #print(i, len(values))
                    letter = values[i][0]
                    #print("First",myTry, letter)

                    pwd += letter
                    if i != len(values)-1:

                        if len(pwd) == len(guess):
                            #print("In if", pwd, myTry)
                            if pwd == guess:
                                print("I found:", pwd)
                                return 1
                            else:

                                pwd = pwd[0:len(pwd)-1]
                        else:

                            myTry += letter
                            myTry = myTry[1:]
                            #print("In else: ",pwd, myTry)
                            return ceva(myTry, good_all, pwd, guess, level)
                    else:
                        if len(pwd) == len(guess):
                            #print("In if", pwd, myTry)
                            if pwd == guess:
                                print("I found:", pwd)
                                return 1

                        pwd = pwd[0:len(pwd)-1]


    for key, letterList in starter_follows.items():
        myTry = key.replace("_", "")

        # i will not treat the case when the starting phrase
        # is a single character
        if myTry == "i":
            pass
        else:
            for letter in letterList:

                if letter[0] not in "_.-\"!":
                    myTry += letter[0]
                    pwd = copy.copy(myTry)
                    #print("Starter:", pwd)
                    res=ceva(myTry, good_all, pwd, toGuess, 1)
                    myTry = myTry[0:len(myTry)-1]

通过这个算法,我达到了最大的递归深度。但是我试图得到所有的马尔可夫链,直到找到密码短语。你知道吗

编辑1:现在,随着更新的代码,密码是找到的,但只是因为我循环所有可能的最后一个字母。你知道吗

例如:“确实”

ind已经在我的起始字母列表中了,我发现的所有三个字母都有“e”作为它们最常见的下一个字母。所以添加了e,然后是下一个e,然后是下一个e,现在密码是“indeee”,但是我将最后一个字母切分,然后再次遍历for,它最终会找到“确实”,这是可以的。 问题是,如果我给出indedd,它将找不到我的密码,因为第二个“d”永远不会循环通过。我怎样才能回到我的迭代中,在所有级别上遍历所有可能的字母?你知道吗