解密蟒蛇

时间:2015-10-04 18:39:16

标签: python caesar-cipher

解密(S)将被给予一系列英文文本移位一些金额。然后,解密应该尽可能地返回原始的英语字符串,这将是输入S的一些旋转(可能是0)。这意味着我必须尝试每种可能的解码并估计它们的英语。

我的方法是使用字母频率:

def list_to_str( L ):
    """ L must be a list of characters; then,
    this returns a single string from them
    """
    if len(L) == 0: return ''
    return L[0] + list_to_str( L[1:] )

我也使用这个公式:

def rot(c, n):
    """ rot rotates c, a single character forward by n spots in the 
        alphabet
        input: a single character
        input: a non-negative integer n between 0 and 25
        output: c forward by n spots in the alphabet
    """
    if 'a' <= c <= 'z':
        neword = ord(c) +n
        if neword > ord('z'):
                neword = neword - 26
    elif 'A' <= c <= 'Z':
        neword = ord(c) + n 
            if neword > ord('Z'):
                neword = neword - 26
    else:                       
        neword = ord(c) 
    return chr(neword)

而且:

def decipher( S ):
    """
    """
    L = [[rot(c, n) for c in S] for n in range(26)]
    LoL = [[sum(letProb(c)) for letter in encoding] for encoding in L ]
    L = max(LoL)
    return list_to_str(L)

最后这个:

LoL = [[sum(letProb(c)) for letter in encoding] for encoding in L ]

前两个公式是好的,但在最后的公式中有一些错误,肯定在句子中:

 jsPlumb.bind("ready", function () {
    jsPlumb.setContainer($("container"));
    jsPlumb.makeSource("src_0", {
        maxConnections: 1,
        isSource: true
    });


    jsPlumb.makeTarget("tgt_0", {
        maxConnections: 1,
        isTarget: true
    });
    jsPlumb.makeTarget("tgt_1", {
        maxConnections: 1,
        isTarget: true
    });
    jsPlumb.makeTarget("tgt_2", {
        maxConnections: 1,
        isTarget: true
    });
});

TypeError:'float'对象不可迭代

2 个答案:

答案 0 :(得分:1)

你正在尝试 sum(letProb(c))其中 letProb 返回一个Float,而 sum 需要一个iterable,一个列表oa发电机,让我们说。尝试这样的事情。

LoL = [[sum(letProb(c) for letter in encoding)] for encoding in L ]

我也认为 c 可能应该是 letter ,但我不是,如果你发布完整的代码, rot 功能包括在内,也许我可以帮助你更好。

答案 1 :(得分:0)

您可能会发现以下内容非常有用。您可以使用某种查找字母概率。如果使用字典,您可以使用get为非A到Z字符提供1.0的默认概率。

其次,Python的string模块有一个make_trans函数,可以与translate一起使用来执行轮换。

import string

letter_probs = {
    'e' : 0.1202, 't' : 0.0910, 'a' : 0.0812, 'o' : 0.0768,
    'i' : 0.0731, 'n' : 0.0695, 's' : 0.0628, 'r' : 0.0602,
    'h' : 0.0592, 'd' : 0.0432, 'l' : 0.0398, 'u' : 0.0288,
    'c' : 0.0271, 'm' : 0.0261, 'f' : 0.0230, 'y' : 0.0211,
    'w' : 0.0209, 'g' : 0.0203, 'p' : 0.0182, 'b' : 0.0149,
    'v' : 0.0111, 'k' : 0.0069, 'x' : 0.0017, 'q' : 0.0011,
    'j' : 0.0010, 'z' : 0.0007}

def rotate(text, rotate_by):
    s_from = string.ascii_lowercase + string.ascii_uppercase
    s_to = string.ascii_lowercase[rotate_by:] + string.ascii_lowercase[:rotate_by] + \
           string.ascii_uppercase[rotate_by:] + string.ascii_uppercase[:rotate_by]
    cypher_table = string.maketrans(s_from, s_to)
    return text.translate(cypher_table)

def sum_probs(text):
    global letter_probs
    return sum(letter_probs.get(c.lower(), 1.0) for c in text)

def decipher(text):
    probabilities = []
    for r in range(26):
        rotated = rotate(text, r)
        probabilities.append((sum_probs(rotated), rotated, r))
    return sorted(probabilities)

for probability, decoded_text, rotate_value in decipher("Mjqqt Btwqi"):
    print '{:2.2f}  {:2}  "{}"'.format(probability, rotate_value, decoded_text)

这将按概率顺序显示所有可能性:

1.17  19  "Fcjjm Umpjb"
1.20  16  "Czggj Rjmgy"
1.22   9  "Vszzc Kcfzr"
1.26  20  "Gdkkn Vnqkc"
1.28  13  "Zwddg Ogjdv"
1.29   4  "Qnuux Fxaum"
1.29  15  "Byffi Qilfx"
1.30   8  "Uryyb Jbeyq"
1.31   6  "Spwwz Hzcwo"
1.32   5  "Rovvy Gybvn"
1.32   0  "Mjqqt Btwqi"
1.33  12  "Yvccf Nficu"
1.34   1  "Nkrru Cuxrj"
1.37  23  "Jgnnq Yqtnf"
1.39   7  "Tqxxa Iadxp"
1.40  22  "Ifmmp Xpsme"
1.40   2  "Olssv Dvysk"
1.44  25  "Lipps Asvph"
1.45  17  "Dahhk Sknhz"
1.47  24  "Khoor Zruog"
1.49  11  "Xubbe Mehbt"
1.52   3  "Pmttw Ewztl"
1.56  10  "Wtaad Ldgas"
1.58  21  "Hello World"
1.61  14  "Axeeh Phkew"
1.68  18  "Ebiil Tloia"

如你所见,答案就在底部附近。