setcode() 的工作就是建立密碼表,我們需要的密碼表就是一個攪亂順序的英文字母表
⇓
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 |
q | z | i | r | a | j | s | b | k | t | c | l | u | d | m | v | e | n | w | f | o | x | g | p | y | h |
先來溫習一下用來編碼的數學公式
y = a * x + b
m = y % n
r = m + diff
a 與 b 預定是 0 到 9 之間的隨機整數,要取得隨機整數的話,標準程式庫 (standard library) 有程式可用,倒是現在先不用急著一次到位,我們先把 a 設定成 3 , b 設定成 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 等於 3 跟 b 等於 5 是沒問題的,可是我們希望 a 與 b 可以是 0 到 9 之間的任意整數,這樣就有 100 種組合說,所以我們接下來要繼續測試,看看是不是每一種組合都 ok 囉!
中英文術語對照 | |
---|---|
屬性 | attribute |
控制變數 | control variable |
函數 | function |
不可變的 | immutable |
迴圈 | loop |
空字串 | null string |
標準程式庫 | standard library |
字串 | string |
重點整理 |
---|
1. 實作 setcode() 是先將公式中的 a 設成 3 , b 設成 5 ,然後用迴圈利用兩個控制變數 i 與 c 逐一計算每個字元。 |
2. 內建函數 ord() 可將字串轉換成 Unicode 編碼數字,而 chr() 將 Unicode 編碼數字轉換回字串。 |
問題與討論 |
---|
1. 為什麼不把建立對換表格直接寫在 __init__() 裡就好了? |
2. 為什麼字串變數用 += 可以把字元附加到字串物件的最後? |
練習 |
---|
1. 承接上一個單元的猜數字遊戲,另寫一個程式 exercise1501.py ,接受使用者輸入,加入判斷使用者是否猜對的邏輯及提示訊息。 |
2. 承上題,另寫一個程式 exercise1502.py ,將 answer 改為字串。 |
相關教學影片