Java 入門指南

單元 13 - Encrypt 類別

~~學習進度表~~

利用 Java 寫程式 (program) ,著重在設計類別 (class) ,然後規劃物件 (object) 的使用、物件與物件間的互動,同時要注意,一個物件專心做好一件事情就好,類別的設計不應該太過複雜

Encrypt → EncryptGUI

我們打算發展的一個替英文句子編密碼的軟體,主要功能是做小寫字母的替換,例如 "There is no spoon." 可能變成以下任一個

Tfqdq ki jo itooj.
Tcnan hf gl fqllg.
Tczmz dn ij nkjji.
Tgfsf pb ir barri.
Tdcpc my fo yxoof.

首先,我們要發展 Encrypt 類別,主要功能是建立一個英文小寫字母的對換表格,藉由這個表格,我們可以將英文句子中的小寫英文字母進行對換,最終開發圖形使用者介面 (graphical user interface) 的 EncryptGUI 專案 (project) 。

GUI 的外觀如下圖

GUI 的部份採用 JavaFX 設計,我們會直接編輯 FXML 檔案, FXML 檔案是 XML 檔案的一種,利用 FXML 設計 GUI 外觀。

Oracle 官方有提供 JavaFX Scene Builder ,利用 JavaFX Scene Builder 可直接在軟體視窗中拉出 JavaFX 的 GUI 外觀,然後由於 Android 開發大量使用 XML ,因此先熟悉編輯 XML ,有助於往後學習 Android 開發。

有兩個可供輸入的文字欄位 (text field) ,其中一個我們作為輸出的顯示訊息之用,另有三個標籤 (label) ,顯示文字的提示訊息,七個按鈕 (button) ,提供新建、載入、儲存 Encrypt 物件,與編碼、解碼所輸入的英文句子,清空所有輸入欄位,以及拷貝輸出結果等的功能。

最後在 Android App 篇,改成直接在手機頁面輸入英文句子,然後點擊編碼按鈕顯示編碼結果

現在我們先來看看所有功能的核心,也就是 Encrypt 類別,我們的目的是,建立一個小寫英文字母的轉換表格,然後編碼、解碼都可直接依據這個表格。我們打算用下面的數學公式建立表格

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

這裡的概念是利用字元的 Unicode 編碼順序,假設 x 為字元的原始編碼, Unicode 編碼中 'a' 為 97 ,然後將 x 乘上變數 (variable) a , 再加上變數 b ,假設兩者均是 0 到 9 的隨機整數,這樣便得到 y 的值。

然後將 y 除以 n 取得餘數 m , n 為所要轉換的字元數量,英文小寫字母共有 26 個,所以這裡 n 等於 26 ,因此 m 等於 0 到 25 之間的整數值。最後將 m 加上 diff , diff 也就是編碼系統的差值,由於 ASCII 中 'a' 為 97 ,所以這裡 diff 要以 97 代入。

因此,餘數 0 的字元會替換成 'a' ,餘數 1 的字元會被替換成 'b' ,餘數 2 的字元會被替換成 'c' ,餘下 23 個字元類推。這樣的計算需要進行 n 次,也就是 26 次,我們最後得到一組餘數與相對應字元的表格,這就是我們需要的表格了。

重複 n 次,我們需要一個迴圈 (loop) ,由於重複次數確定,因此 for 迴圈 (for loop) 很適合,那我們要用什麼東西來儲存這個表格呢? API 中有許多的資料結構 (data structure) ,可以依資料特性有效率的處理資料,簡單一點,我們利用陣列 (array) 就可以了。

陣列是一種儲存可以多個相同型態資料的資料結構,索引值 (index) 從 0 開始,這也完全符合我們計算餘數從 0 開始的需求。

我們先寫一個 Encrypt 的試做版本 Encrypt01 來看看吧

/*
 * 檔名:Encrypt01.java
 * 作者:張凱慶
 * 網站:http://kaiching.org
 */
 package encrypt01;
 
 public class Encrypt01 {
    // 密碼表字元陣列
    private char[] code = new char[26];
    
    // 建構子
    public Encrypt01() {
        setCode();
    }
    
    // setter
    public void setCode() {
        char c = 'a';
        for (int i = 0; i < 26; i++) {
            code[i] = 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) {
        Encrypt01 e = new Encrypt01();
        System.out.println(e.code);
        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);
    }
}

首先宣告 private 的密碼表字元陣列屬性 code

// 密碼表字元陣列
private char[] code = new char[26];

這裡用 new 建立陣列物件,目的是宣告完直接分配記憶體空間。

下面除了建構子 (constructor) 及 setCode() 、 getCode() 外,還有需要一個 String 參數 (parameter) 也回傳 String 的 toEncode() 與 toDecode() ,這兩個都暫時回傳參數,待稍候的單元再實作。

建構子簡單的呼叫 setCode() ,目前 setCode() 的版本為建立二十六個英文小寫字母表

// setter
public void setCode() {
    char c = 'a';
    for (int i = 0; i < 26; i++) {
        code[i] = c++;
    }
}

這也是個暫時的版本,讓我們測試的 main() 可以正常運作

// 測試的 main()
public static void main(String[] args) {
    Encrypt01 e = new Encrypt01();
    System.out.println(e.code);
    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);
}

Encrypt01.java 也可看成是列出 Encrypt 類別的軟體規格。

執行結果如下

abcdefghijklmnopqrstuvwxyz
There is no spoon.
There is no spoon.
There is no spoon.

接下來我們要在 setCode() 中實作製作密碼表的公式囉!

相關教學影片

上一頁 軟體開發篇
回 Java 入門指南首頁
下一頁 單元 14 - 實作 setCode()
回 Java 教材首頁
回程式語言教材首頁
中英文術語對照
array陣列
button按鈕
class類別
constructor建構子
data structure資料結構
for loopfor 迴圈
graphical user interface圖形使用者介面
index索引值
label標籤
loop迴圈
object物件
parameter參數
program程式
project專案
text field文字欄位
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. Encrypt 類別的主類功能是轉換句子中的英文小寫字母,最後作為 GUI 軟體的核心部分。
2. Encrypt 類別以數學公式建立英文字母的轉換表格,用字串當欄位儲存表格。
3. Unicode 中, 'a' 的整數值為 97 。
4. 軟體通常是逐步發展而成。
問題與討論
1. 為什麼 Encrypt 類別是要當作 GUI 軟體的核心?不能讓 Encrypt 類別直接成為大展神威的 GUI 軟體嗎?
2. 除了數學公式外,有其他的方式可以建立轉換表格嗎?
3. 為什麼程式的發展要逐步來?不能一次到位嗎?
4. 字串是什麼樣的資料結構?對於儲存資料有什麼方便性?
練習
1. 建立一個專案 Exercise1301 ,設定一個含有數字 0 到 9 的字串,然後利用字串的 substring() 方法,印出 substring(6) 及 substring(0, 4) 。
2. 猜數字遊戲是一種猜測四位不重複數字的小遊戲,依猜測答案給 A 及 B 的數量, A 為對的數字及位置, B 為對的數字錯的位置,建立一個專案 Exercise1302 ,加入新的類別 GGuess 類別,自訂答案整數型態的 answer 欄位,然後在 Exercise1302 類別的 main() 印出 answer 值。