Java 入門指南

單元 14 - 實作 setCode()

~~學習進度表~~

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

setCode()

012345678910111213141516171819202122232425
qzirajsbktcludmvenwfoxgpyh

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

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

ab 預定是 09 之間的隨機整數,要取得隨機整數的話, API 有程式可用,倒是現在先不用急著一次到位,我們先把 a 設定成 3b 設定成 5 好了, setCode() 的實作如下

// setter
public void setCode() {
    int a = 3;
    int b = 5;
        
    int x, y, m, i;
    char c = 'a';
    for (i = 0; i < 26; i++) {
        x = c;
        y = x * a + b;
        m = y % 26;
        code[i] = (char) (m + 97);
        c++;
    }
}

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

for (i = 0; i < 26; i++) {
    x = c;
    y = x * a + b;
    m = y % 26;
    code[i] = (char) (m + 97);
    c++;
}

我們多用了除了公式外的變數 (variable) cc 為起始字元 (character) ,初值設定成英文字母表的第一個字母 'a' ,這裡並沒有直接拿變數 c 進行計算,而是把變數 c 的值指派給整數型態的 x

x = c;

會這樣做的原因很簡單,因為需要一個變數表示目前處理的字元,而字元型態的變數可以如同整數型態進行加減乘除,因此迴圈的最後利用遞增將變數 c 轉移到下一個字元,例如迴圈從 'a' 開始,第二個處理的字元為 'b' ,第三個為 'c' ,以此類推

c++;

Java 的字元型態其實就是 Unicode 編碼,因此可做算術運算。

然後當計算完的餘數 m 要加上 97 ,這才恢復成 Unicode 編碼中英文小寫字母的範圍,同時用小括弧進行強制型態轉換

code[i] = (char) (m + 97);

然後直接將計算結果指派當作 code 的元素,逐一跑完 26 次就得到密碼表字元陣列了。

建構函數 Encrypt() 就是呼叫 setCode() 設定 code ,另外 getCode() 也就是回傳 code ,我們把 Encrypt01 改成 Encrypt02 如下

/*
 * 檔名:Encrypt02.java
 * 作者:張凱慶
 * 網站:http://kaiching.org
 */
 package encrypt02;
 
 public class Encrypt02 {
    // 密碼表字元陣列
    private char[] code = new char[26];
    
    // 建構子
    public Encrypt02() {
        setCode();
    }
    
    // setter
    public void setCode() {
        int a = 3;
        int b = 5;
        
        int x, y, m, i;
        char c = 'a';
        for (i = 0; i < 26; i++) {
            x = c;
            y = x * a + b;
            m = y % 26;
            code[i] = (char) (m + 97);
            c++;
        }
    }
    
    // getter
    public char[] getCode() {
        return code;
    }
    
    // 編碼的方法
    public String toEncode(String s) {
        return s;
    }
    
    // 解碼的方法
    public String toDecode(String s) {
        return s;
    }
    
    // 測試的 main()
    public static void main(String[] args) {
        Encrypt02 e = new Encrypt02();
        System.out.println(e.getCode());
        String s = "There is no spoon.";
        System.out.println(s);
        String s1 = e.toEncode(s);
        System.out.println(s1);
        String s2 = e.toDecode(s1);
        System.out.println(s2);
    }
}

執行結果如下

knqtwzcfiloruxadgjmpsvybeh
There is no spoon.
There is no spoon.
There is no spoon.

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

相關教學影片

上一篇 單元 13 - Encrypt 類別
回 Java 入門指南首頁
下一篇 單元 15 - 繼續測試
回 Java 教材首頁
回程式語言教材首頁
中英文術語對照
character字元
loop迴圈
variable變數
1. The Java™ Tutorials: Declaring Classes
2. The Java™ Tutorials: Declaring Member Variables
3. The Java™ Tutorials: Defining Methods
4. The Java™ Tutorials: Providing Constructors for Your Classes
5. The Java™ Tutorials: Returning a Value from a Method
6. The Java™ Tutorials: Using the this Keyword
7. The Java™ Tutorials: Controlling Access to Members of a Class
8. The Java™ Tutorials: Understanding Class Members
9. The Java™ Tutorials: Initializing Fields
重點整理
1. 實作 setCode() 是先將公式中的 a 設成 3b 設成 5 ,然後用迴圈利用兩個控制變數 ic 逐一計算每個字元。
2. 字元型態就是範圍較小的整數,因此可直接進行算術運算。
問題與討論
1. 為什麼不把建立對換表格直接寫在建構子裡就好了?
2. 為什麼要用小括弧圍住型態名稱,像是 (char)
練習
1. 承接上一個單元的猜數字遊戲,另建立一個專案 Exercise1401 ,在 Exeercise1401 類別的 main() 方法接受使用者輸入,加入判斷使用者是否猜對的邏輯及提示訊息。
2. 承上題,另建立一個專案 Exercise1402 ,將 answer 改為字串。