
上圖是用了如下的表格
cArray = { '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' }; |
對以下的字串而言
"There is no spoon." ; |
我們先來想一想程式應該如何完成這一項工作,首先, 'T' 不是英文小寫字母,因此跳過,然後 'h' 、 'e' 、 'r' 、 'e' 都是英文小寫字母,對照表格,需要轉換為 'b' 、 'a' 、 'n' 、 'a' ,接下來遇到一個空格字元 ' ' ,也跳過,然後 'i' 、 's' 也都是英文小寫字母,需要轉換為 'k' 、 'w' ,餘下類推。
所以需要利用一個迴圈 (loop) 進行上述編碼工作,逐一檢查字串中的每一個字元 (character) ,若是屬於英文小寫字母的編碼範圍,在 Unicode 就是 97 到 122 之間,先將該字元轉換為整數,然後減掉 97 就會是表格中對應字元的 Unicode 編碼值。
這是說,第 0 個字元(索引值為 0 ) 'T' 不在英文小寫字母編碼的範圍,因此程式不會處理,然後到第 1 個字元 'h' ,這是英文小寫字母編碼為 84 ,減去 97 之後為 7 ,對應到上面的表格會是 'b' ,因此得到的新字串第 1 個新字元就是 'b' ,餘下會一直進行重複的工作到字串結束為止。
因此,我們對編碼方法 (method) 設計如下
public string toEncode( string s) { System.Text.StringBuilder r = new System.Text.StringBuilder(); // 進行編碼轉換 char c; int i, m; for (i = 0; i < s.Length; i++) { if (s[i] >= 97 && s[i] <= 122) { c = s[i]; m = c - 97; r.Append( this .Code[m]); } else { r.Append(s[i]); } } // 回傳字串 return r.ToString(); } |
toEncode() 接收一個字串當參數,也回傳一個新字串。我們在 toEncode() 建立一個暫存的 StringBuilder ,這是因為字串被設計成不可變的 (immutable) ,也就是說,字串一旦被建立後,就不能再被更改內容,所以藉由可變的 StringBuilder 來進行這項工作,最後再回傳字串。
進行編碼轉換的迴圈
// 進行編碼轉換 char c; int i, m; for (i = 0; i < s.Length; i++) { if (s[i] >= 97 && s[i] <= 122) { c = s[i]; m = c - 97; r.Append( this .Code[m]); } else { r.Append(s[i]); } } |
字串的屬性 (property) Length 為字串中元素的個數,迴圈的控制變數 i 最大不超過 s.Length ,因為陣列索引從 0 開始,最後一個元素的索引為 Length - 1 。留意這一行
if (s[i] >= 97 && s[i] <= 122) { |
只有英文小寫字母,也就是 Unicode 字元編碼在 97 到 122 之間,才會進行編碼轉換。底下第一個動作
c = s[i]; |
由 c 取得 s 中的元素,然後
m = c - 97; |
m 為該字元為第幾個英文字母,這可直接對應到表格,因此用 m 取得表格中的元素,亦即要轉換的字元
r.Append( this .Code[m]); |
若非英文小寫字母,也就是 Unicode 字元編碼在 97 到 122 之外,就直接將該字元加進 r 之中
r.Append(s[i]); |
完整的 Encrypt 修改如下
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 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | class Encrypt { private string cArray; public string Code { get { return cArray; } set { if (value is string && value.Length == 26) { cArray = value; } else { System.Console.WriteLine( "something worng!!" );; } } } public Encrypt() { System.Random r = new System.Random(); int a = 0; int b = 0; // 限定 a 為偶數 while (a % 2 == 0) { a = r.Next(1, 10); b = r.Next(1, 10); } System.Console.Write( "a: " + a + ", b: " + b + ", " ); int x, y, m; char c = 'a' ; int i; System.Text.StringBuilder s = new System.Text.StringBuilder(); for (i = 0; i < 26; i++) { x = c; y = x * a + b; m = y % 26; s.Append(( char ) (m + 97)); c++; } this .cArray = s.ToString(); } public string toEncode( string s) { System.Text.StringBuilder r = new System.Text.StringBuilder(); // 進行編碼轉換 char c; int i, m; for (i = 0; i < s.Length; i++) { if (s[i] >= 97 && s[i] <= 122) { c = s[i]; m = c - 97; r.Append( this .Code[m]); } else { r.Append(s[i]); } } // 回傳字串 return r.ToString(); } static void Main() { string s = "There is no spoon." ; for ( int i = 0; i < 16; i++) { Encrypt e = new Encrypt(); System.Console.WriteLine(i + ": " + e.toEncode(s)); System.Threading.Thread.Sleep(1000); } } } /* 《程式語言教學誌》的範例程式 檔名:encrypt.cs 功能:示範 C# 程式 作者:張凱慶 時間:西元 2012 年 10 月 */ |
我們只對 "There is no spoon." 進行編碼,總共 16 次,每一次採用不同的轉換表格。測試結果如下

接下來,我們繼續加入解碼的功能吧!
中英文術語對照 | |
---|---|
編碼 | encoding |
字串 | string |
陣列 | array |
迴圈 | loop |
字元 | character |
方法 | method |
不可變的 | immutable |
屬性 | property |
您可以繼續參考
軟體開發
相關目錄
回 C# 入門指南
回 C# 教材
回首頁
參考資料
http://msdn.microsoft.com/zh-tw/library/ms173109%28v=vs.80%29.aspx
http://msdn.microsoft.com/zh-tw/library/x9afc042.aspx
http://msdn.microsoft.com/zh-tw/library/ms229036%28v=vs.80%29.aspx
http://msdn.microsoft.com/zh-tw/library/0b0thckt.aspx
沒有留言:
張貼留言