Python 入門指南 V2.00 - 單元 15 - 實作 setcode()




setcode() 的工作就是建立密碼表,我們需要的密碼表就是一個攪亂順序的英文字母表



先來溫習一下用來編碼的數學公式


y = a * x + b
m = y % n
r = m + diff


ab 預定是 09 之間的隨機整數,要取得隨機整數的話,標準模組庫 (standard library) 有程式可用,倒是現在先不用急著一次到位,我們先把 a 設定成 3b 設定成 5 測試看看好了,如此 setcode() 的實作如下


   def setcode(self):
      # 取得 a 、 b 值
      a = 3
      b = 5
      
      # 利用公式建立密碼表
      self.code = ""
      c = "a"
      i = 0
      while i < 26:
         x = c
         y = ord(x) * a + b
         m = y % 26
         self.code += chr(m + 97)
         c = chr(ord(c) + 1)
         i += 1

code 屬性 (attribute) 的初值設定為空字串 (null string)


   self.code = ""

下面設定兩個控制變數 (control variable) , c 為記錄目前處理的字母, i 則是記錄迴圈 (loop) 進行的次數


   c = "a"
   i = 0

因為英文字母表的小寫字母共有 26 個,因此公式用迴圈跑了 26


   while i < 26:
      x = c
      y = ord(x) * a + b
      m = y % 26
      self.code += chr(m + 97)
      c = chr(ord(c) + 1)
      i += 1

這裡把 c 指派給 x 後,因為 c 是字串 (string) ,使得 x 也是字串,由於字串做乘法跟加法為複製字串,所以用內建函數 (function) ord()x 轉換成 Unicode 編碼值,然後才進行計算


   y = ord(x) * a + b

取得餘數 m 後,再利用內建函數 chr() 將 Unicode 編碼值轉換為單一字母的字串,這裡 += 會把單一字母的字串附加到 code 的最後


   self.code += chr(m + 97)

咦?不是說字串是不可變的 (immutable) 嗎?不可變的複合物件無法更改裡頭的元素值,那這裡為什麼可以這樣寫呢?原因很簡單,這裡是重新指派,每一次 += 都是把新的字串物件給 code ,所以沒有涉及到更改內容的問題。

最後,兩個控制變數都要遞增


   c = chr(ord(c) + 1)
   i += 1

我們把目前的版本放在 encrypt02.py 裡,如下


001# 定義 Encrypt 類別 
002class Encrypt:
003   def __init__(self):
004      self.setcode()
005
006   def setcode(self):
007      # 取得 a 、 b 值
008      a = 3
009      b = 5
010      
011      # 利用公式建立密碼表
012      self.code = ""
013      c = "a"
014      i = 0
015      while i < 26:
016         x = c
017         y = ord(x) * a + b
018         m = y % 26
019         self.code += chr(m + 97)
020         c = chr(ord(c) + 1)
021         i += 1
022
023   def getcode(self):
024      return self.code
025
026   # 編碼的方法
027   def toEncode(self, str):
028      pass
029
030   # 解碼的方法 
031   def toDecode(self, str):
032      pass
033
034# 測試部分
035if __name__ == '__main__':
036   e = Encrypt()
037   print()
038   print(e.getcode())
039   print()
040 
041# 檔名: encrypt02.py 
042# 作者: Kaiching Chang 
043# 時間: July, 2014

測試部分就是印出密碼表,執行結果如下



結果如預期,一個英文小寫字母恰恰好對應到另外一個英文小寫字母,這樣我們的公式就 ok 了嗎? a 等於 3b 等於 5 是沒問題的,可是我們希望 ab 可以是 09 之間的任意整數,這樣就有 100 種組合說,所以我們接下來要繼續測試,看看是不是每一種組合都 ok 囉!


中英文術語對照


標準模組庫standard library
屬性attribute
空字串null string
控制變數control variable
迴圈loop
字串string
函數function
不可變的immutable

重點整理


  1. 實作 setcode() 是先將公式中的 a 設成 3b 設成 5 ,然後用迴圈利用兩個控制變數 ic 逐一計算每個字元。
  2. 內建函數 ord() 可將字串轉換成 Unicode 編碼數字,而 chr() 將 Unicode 編碼數字轉換回字串,


問題與討論


  1. 為什麼不把建立對換表格直接寫在 __init__() 裡就好了?
  2. 為什麼字串變數用 += 可以把字元附加到字串物件的最後?

練習


  1. 承接上一個單元的猜數字遊戲,另寫一個程式 exercise1501.py ,接受使用者輸入,加入判斷使用者是否猜對的邏輯及提示訊息。
  2. 承上題,另寫一個程式 exercise1502.py ,將 answer 改為字串。

the end

沒有留言: