Python 入門指南

單元 15 - 實作 setcode()

~~學習進度表~~

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

setCode()

012345678910111213141516171819202122232425
qzirajsbktcludmvenwfoxgpyh

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

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 也是字串,由於字串做乘法跟加法為複製字串,所以用內建函數 (built-in 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 裡,如下

# 定義 Encrypt 類別 
class Encrypt:
  def __init__(self):
    self.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
    
  def getcode(self):
    return self.code
    
  # 編碼的方法
  def toEncode(self, str):
    pass
    
  # 解碼的方法
  def toDecode(self, str):
    pass
    
# 測試部分
if __name__ == '__main__':
  e = Encrypt()
  print()
  print(e.getcode())
  print()
  
#《程式語言教學誌》的範例程式
# http://kaiching.org/
# 檔名:encrypt02.py
# 功能:示範利用 Python 設計 Encrypt 類別
# 作者:張凱慶 */

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

$ python encrypt02.py
 
knqtwzcfiloruxadgjmpsvybeh
 
$

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

中英文術語對照
屬性attribute
控制變數control variable
函數function
不可變的immutable
迴圈loop
空字串null string
標準程式庫standard library
字串string
重點整理
1. 實作 setcode() 是先將公式中的 a 設成 3b 設成 5 ,然後用迴圈利用兩個控制變數 ic 逐一計算每個字元。
2. 內建函數 ord() 可將字串轉換成 Unicode 編碼數字,而 chr() 將 Unicode 編碼數字轉換回字串。
問題與討論
1. 為什麼不把建立對換表格直接寫在 __init__() 裡就好了?
2. 為什麼字串變數用 += 可以把字元附加到字串物件的最後?
練習
1. 承接上一個單元的猜數字遊戲,另寫一個程式 exercise1501.py ,接受使用者輸入,加入判斷使用者是否猜對的邏輯及提示訊息。
2. 承上題,另寫一個程式 exercise1502.py ,將 answer 改為字串。

相關教學影片

上一頁 單元 14 - Encrypt 類別
回 Python 入門指南首頁
下一頁 單元 16 - 繼續測試
回 Python 教材首頁
回程式語言教材首頁