2012-05-29 131 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 

他們離開擴大到「顯示我的工作」的教程練習。