C# 入門指南

單元 14 - Encrypt 類別

~~學習進度表~~

類別 (class) 為 Python 開發軟體 (software) 的要角,因為類別用來設計物件 (object) ,軟體的實際運作則是藉由物件與物件的互動。我們接下來進入實際開發軟體的階段,到 WPF App 篇會發展出一個 GUI 軟體,而在 Android App 篇會把發展出的 Encrypt 類別應用在 Android App 中

     Encrypt
         ⇘
       EncryptWpfApp
       Android App

我們打算發展的一個替英文句子編密碼的軟體,主要功能是做小寫字母的替換,例如 "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) 的 EncryptWpfApp 專案及 Android App 的 EncryptAndroidApp 專案。

GUI 的外觀如下圖

WFP 為 Windows Presentation Foundation 的頭字母縮寫詞,其為微軟在 .NET 3.0 之後推的 Windows App 開發框架,基於技術開發向新的看齊的緣故,這裡採用比較新的開發框架作介紹。

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

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

在 Visual Studio Community 2019 開發 Andorid App 需要額外安裝 Android SDK ,詳情請參考官方文件 Xamarin | Microsoft Docs - 設定 Xamarin.Android 的 Android SDK

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

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

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

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

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

重複 n 次,我們需要一個迴圈 (loop) ,由於重複次數確定,因此 while 迴圈 (while loop) 就可以了,那我們要用什麼東西來儲存這個表格呢? C# 有很多內建的資料結構 (data structure) ,可以依資料特性有效率的處理資料,這裡,我們利用字串 (string) 就可以了。

字串類似字元陣列,這意思是說,字串可像陣列用索引值存取裡頭的元素 (element) ,也就是長度為 1 的字元,索引值恰巧是從 0 開始,這也完全符合我們計算餘數從 0 開始的需求。

我們先寫個開發規格的版本,如下

using System;

namespace EncryptDemo01
{
    class EncryptDemo01
    {
        // 宣告密碼表欄位
        public string code;

        // 建構子,呼叫建立密碼表的 SetCode() 方法
        public EncryptDemo01()
        {
            SetCode();
        }

        // 建立密碼表
        public void SetCode()
        {
            code = "code";
        }

        // 編碼方法
        public string ToEncode(string s)
        {
            return s;
        }

        // 解碼方法
        public string ToDecode(string s)
        {
            return s;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            // 建立密碼物件
            EncryptDemo01 e = new EncryptDemo01();
            // 印出密碼表
            Console.WriteLine(e.code);
            // 印出編碼方法的回傳值
            string s1 = e.ToEncode("Hello");
            Console.WriteLine(s1);
            // 印出解碼方法的回傳值
            string s2 = e.ToDecode("World");
            Console.WriteLine(s2);
        }
    }
}
  
//《程式語言教學誌》的範例程式
// http://kaiching.org/
// 專案:EncryptDemo01
// 檔名:Program.cs
// 功能:示範利用 C# 設計 Encrypt 類別
// 作者:張凱慶

開發規格版本 EncryptDemo01 的建構子就是呼叫 SetCode()

// 建構子,呼叫建立密碼表的 SetCode() 方法
public EncryptDemo01()
{
    SetCode();
}

密碼表預計儲存在 code 欄位,這裡 SetCode() 先簡單指派 "code" 字串給 code

// 建立密碼表
public void SetCode()
{
    code = "code";
}

負責編碼與解碼的 ToEncode()ToDecode() 方法則是先寫出來,

// 編碼方法
public string ToEncode(string s)
{
    return s;
}

// 解碼方法
public string ToDecode(string s)
{
    return s;
}

此例執行結果如下

C:\EncryptDemo01> dotnet run
code
Hello
World
C:\EncryptDemo01>

EncryptDemo01 專案為 Encrypt 類別基本的規格,接下來我們把公式放進 SetCode() ,來建立實際的密碼表囉!

相關教學影片

上一篇 軟體開發篇
回 C# 入門指南首頁
下一篇 單元 15 - 實作 SetCode()
回 C# 教材首頁
回程式語言教材首頁
中英文術語對照
按鈕button
類別class
資料結構data structure
元素element
圖形使用者介面graphical user interface
標籤label
迴圈loop
物件object
軟體software
字串string
文字欄位text field
變數variable
while 迴圈while loop
參考資料
1. Visual Studio | Microsoft Docs - 教學課程:使用 C# 建立一個簡單的應用程式
2. Visual Studio | Microsoft Docs - Xamarin.Android 使用者入門
重點整理
1. Encrypt 類別的主類功能是轉換句子中的英文小寫字母,最後作為 GUI 軟體的核心部分。
2. Encrypt 類別以數學公式建立英文字母的轉換表格,用字串當欄位儲存表格。
3. Unicode 中, 'a' 的整數值為 97
4. 軟體通常是逐步發展而成。
問題與討論
1. 為什麼 Encrypt 類別是要當作 GUI 軟體的核心?不能讓 Encrypt 類別直接成為大展神威的 GUI 軟體嗎?
2. 除了數學公式外,有其他的方式可以建立轉換表格嗎?
3. 為什麼程式的發展要逐步來?不能一次到位嗎?
4. 字串是什麼樣的資料結構?對於儲存資料有什麼方便性?
練習
1. 建立一個專案 Exercise1401 ,設定一個含有數字 09 的字串,然後利用字串的 Substring() 方法,印出 Substring(6)Substring(0, 4)
2. 猜數字遊戲是一種猜測四位不重複數字的小遊戲,依猜測答案給 A 及 B 的數量, A 為對的數字及位置, B 為對的數字錯的位置,建立一個專案 Exercise1402 ,定義 Guess 類別,自訂答案整數型態的 answer 欄位,然後在 Program 類別的 Main() 印出 answer 值。