Java 入門指南 V2.00 - 單元 14 - 實作 setCode()




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



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


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


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


010// setter
011public void setCode() {
012   int a = 3;
013   int b = 5;
014
015   int x, y, m, i;
016   char c = 'a';
017   for (i = 0; i < 26; i++) {
018      x = c;
019      y = x * a + b;
020      m = y % 26;
021      code[i] = (char) (m + 97);
022      c++;
023   }
024}

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


017for (i = 0; i < 26; i++) {
018   x = c;
019   y = x * a + b;
020   m = y % 26;
021   code[i] = (char) (m + 97);
022   c++;
023}

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


018x = c;

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


022c++;

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

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


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

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


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


001public class Encrypt02 {
002   // 密碼表字元陣列
003   private char[] code = new char[26];
004
005   // 建構子
006   public Encrypt02() {
007      setCode();
008   }
009
010   // setter
011   public void setCode() {
012      int a = 3;
013      int b = 5;
014
015      int x, y, m, i;
016      char c = 'a';
017      for (i = 0; i < 26; i++) {
018         x = c;
019         y = x * a + b;
020         m = y % 26;
021         code[i] = (char) (m + 97);
022         c++;
023      }
024   }
025
026   // getter
027   public char[] getCode() {
028      return code;
029   }
030
031   // 編碼的方法
032   public String toEncode(String s) {
033      return s;
034   }
035
036   // 解碼的方法
037   public String toDecode(String s) {
038      return s;
039   }
040
041   // 測試的 main()
042   public static void main(String[] args) { 
043      Encrypt02 e = new Encrypt02();
044      System.out.println(e.getCode());
045      String s = "There is no spoon";
046      System.out.println(s);
047      String s1 = e.toEncode(s);
048      System.out.println(s1);
049      String s2 = e.toDecode(s1);
050      System.out.println(s2);
051   }
052}
053 
054/* 檔名: Encrypt02.java
055   作者: Kaiching Chang
056   時間: September, 2014 */

編譯執行,結果如下



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


中英文術語對照


迴圈loop
變數variable
字元character

重點整理


  1. setCode() 為 code 的 setter ,用數學公式設定 code 。
  2. 字元型態就是 Unicode 編碼,因此可做算術運算

問題與討論


  1. 公式中取得餘數後,可以不做強制型態轉換嗎?
  2. 想一想公式會不會有問題?公式有可能會出什麼樣的錯?

the end

沒有留言: