2012-05-29 140 views
4

在我的课程中,我的任务是创建一个凯撒密码解码器,它需要一串输入并使用字母频率找到最好的字符串。如果不知道多少意义,但让问题发布:Python凯撒密码解码器

编写一个程序,它执行以下操作。首先,它应该读取一行输入,这是编码的消息,并将包含大写字母和空格。您的程序必须尝试使用​​所有26个可能的值S来解码消息;在这26个可能的原始信息中,打印出最具善意的那一个。 为方便起见,我们会预先为您定义的变量letterGoodness,长度26的列表,它等于上述

Letter Frequencies

频率表中的值我到目前为止这样的代码:

x = input() 
NUM_LETTERS = 26 #Can't import modules I'm using a web based grader/compiler 
def SpyCoder(S, N): 
    y = "" 
    for i in S: 
     x = ord(i) 
     x += N 
     if x > ord('Z'): 
      x -= NUM_LETTERS 
     elif x < ord('A'): 
      x += NUM_LETTERS 
     y += chr(x) 
    return y 

def GoodnessFinder(S): 
    y = 0 
    for i in S: 
     if x != 32: 
      x = ord(i) 
      x -= ord('A') 
      y += letterGoodness[x] 
    return y 

def GoodnessComparer(S): 
    goodnesstocompare = GoodnessFinder(S) 
    goodness = 0 
    v = '' 
    for i in range(0, 26): 
     v = SpyCoder(S, i) 
     goodness = GoodnessFinder(v) 
     if goodness > goodnesstocompare: 
      goodnesstocompare = goodness 
    return v 

y = x.split() 
z = '' 
for i in range(0, len(y)): 
    if i == len(y) - 1: 
     z += GoodnessComparer(y[i]) 
print(z) 

编辑:由Cristian Ciupitu建议更改 请忽略缩进错误,它们可能在我复制我的代码时出现。

的程序是这样的:

  • 就拿输入,并将其分割成一个列表
  • 对于每一个列表值我将其提供给一个善良取景器。
  • 它需要字符串的好处,并将其他所有内容进行比较,当有更高的善意时,它会使得更高的善良性比较。
  • 它然后我偏移量文本的该字符串,看看优度较高或较低

我不太清楚是哪里的问题,第一个测试:LQKP OG CV GKIJV DA VJG BQQ
打印正确的消息:JOIN ME AT在由ZOO

然而接下来的测试:UIJT JT乙TBNQMF MJOF PG UFYU GPS EFDSZQUJOH
给出的垃圾字符串:SGHR HRžRZLOKD KHMD NE SDWS ENQ CDBQXOSHMF
当它应该是:这是一个示例文本的DECRYPTIN摹

我知道我必须:
想尽一切移值
获取字
返回字符串最高善良“善良”。

我希望我的解释有意义,因为我现在很困惑。

+1

如果你为垃圾字符串'SGHR HR Z RZLOKD ...'中的每个字符加1,你会得到'THIS IS A SAMPLE ...',所以它几乎是正确的。 –

+3

你应该尝试用有意义的常量替换一些神奇的数字,例如65用'ord('A')',26用'NUM_LETTERS'。顺便说一下'GoodnessComparer'你有'range(0,25)'而不是'(0,26)';这是一个错字还是不是?还有一件事:在GoodnessFinder中,每次只需要'i'是一个空格(''''')时,你不需要执行'ord(i)'。 –

+0

[input()](http://docs.python.org/library/functions.html#input)与'eval(raw_input())'等价,这是没有意义的,所以用一个普通的' raw_input()'调用。 –

回答

2

我的最终解决方案有效,这要感谢奇妙的克里斯蒂安Ciupitu。

x = input() 
NUM_LETTERS = 26 #Can't import modules I'm using a web based grader/compiler 
def SpyCoder(S, N): 
    y = "" 
    for i in S: 
     if(i.isupper()): 
     x = ord(i) 
     x += N 
     if x > ord('Z'): 
      x -= NUM_LETTERS 
     elif x < ord('A'): 
      x += NUM_LETTERS 
     y += chr(x) 
     else: 
     y += " " 
    return y 

def GoodnessFinder(S): 
    y = 0 
    for i in S: 
     if i.isupper(): 
     x = ord(i) 
     x -= ord('A') 
     y += letterGoodness[x] 
     else: 
     y += 1 
    return y 

def GoodnessComparer(S): 
    goodnesstocompare = GoodnessFinder(S) 
    goodness = 0 
    v = '' 
    best_v = S 
    for i in range(0, 26): 
    v = SpyCoder(S, i) 
    goodness = GoodnessFinder(v) 
    if goodness > goodnesstocompare: 
     best_v = v 
     goodnesstocompare = goodness 
    return best_v 


print(GoodnessComparer(x)) 

谢谢大家的帮助!

3

这是我的实施,它工作正常。

你应该打印每个可能的消息的好处,并看看你的程序输出它的原因。

letterGoodness = dict(zip(string.ascii_uppercase, 
         [.0817,.0149,.0278,.0425,.1270,.0223,.0202, 
         .0609,.0697,.0015,.0077,.0402,.0241,.0675, 
         .0751,.0193,.0009,.0599,.0633,.0906,.0276, 
         .0098,.0236,.0015,.0197,.0007])) 

trans_tables = [ str.maketrans(string.ascii_uppercase, 
       string.ascii_uppercase[i:]+string.ascii_uppercase[:i]) 
       for i in range(26)] 

def goodness(msg): 
    return sum(letterGoodness.get(char, 0) for char in msg) 

def all_shifts(msg): 
    msg = msg.upper() 
    for trans_table in trans_tables: 
     txt = msg.translate(trans_table) 
     yield goodness(txt), txt 

print(max(all_shifts(input()))) 
+1

你已经注意到了*作业*标签,对吧?你的回答太好了。 –

+1

@CristianCiupitu:所以他不能只提交它,而是先学习。 – Kabie

0

我正在研究相同的教程,并使用了一个稍微不同的方法。这避免了创建和调用函数:

inp = input()  #to hold code text 
code = list(inp) #store code as a list 
soln = []   #store the 'Goodness' for each of 26 possible answers 
y=0    #variable to hold total goodness during calculations 
clear = []  #will hold decoded text 
pos=0    #position marker for a list 

#for every possible value of shift 
#note range as 0 to 25 are valid shifts and shift 26 = shift 0 

for shift in range(0,26): 
    for i in code:     #loop through each letter in code 
     if i == " ":     #spaces have no score so omit them 
     continue 
     else:      #if it's a letter 
     x = ord(i)-shift   #apply the test shift 
     if x < 65:    #prevent shifting outside A-Z range 
      x = x + 26    
     x = x - 64    #turn ord into character position in A-Z with A=1 
     x = letterGoodness[x-1] #turn this into the Goodness score 
     y = y + x     #add this to a running total 
    soln.insert(shift-1,y)   #AFTER decoding all letters in code, add total(y) to list of scores 
    y = 0       #reset y before next test value 

bestSoln=max(soln)     #find highest possible score 

for i in range(0,26):    #check the list of solutions for this score 
    if soln[i]==bestSoln:   #the position in this list is the shift we need 
     bestShift = i+1    #+1 as the first solution is 0 

for i in code:      #now decode the original text using our best solution 
    if i == " ":     #spaces are not encoded so just add these to the string 
     clear.insert(pos," ")  #pos used to track next position for final string 
     pos = pos + 1 
     continue 
    else: 
     x = ord(i)-bestShift   #same operation as before 
     if x < 65: 
     x = x + 26 
    z = chr(x) 
    clear.insert(pos,z)    #add the decoded letter to the clear text 
    pos = pos + 1 
print("".join(clear))    #join the list of clear text into one string and print it 

注意,该代码的很多地方可以(也应该)被压缩,例如

x = x - 64 
x = letterGoodness[x-1] 
y = y + x 

他们离开扩大到“显示我的工作”的教程练习。