# 北軟96 pA 10Bytes編解碼程式 ###### tags: `北軟96` ## 題目 電腦上常需要將資料編解碼以方便儲存及處理。請將身分證字號、出生年月日、婚姻、學歷、 手機號碼等個人資料編碼成 10 Bytes 的大小。 1. 請設計如下版面,身分證字號欄能放 10 個英數字、出生年月日 8 個數字、婚姻有 2 種選項、學歷有 8 種選項、手機號碼欄能放 10 個數字。【7 分】 2. 10 Bytes 共有 80 Bits,身分證字號右 8 位數放在 80Bits 的 bit26-0、身分證字號第 2 位數放在 80Bits的 bit27(0 表男、1 表女)、身分證字號左邊第 1 位數的英文字母放在 80Bits 的 bit32-28(00000 表 A、11001 表 Z)。 3. 出生年月日的 “日” 放在 80Bits 的 bit37-33(00001 表 1 日、11111 表 31 日),“月” 放在 80Bits的 bit41-38(0001 表一月、1100 表十二月),“月” 放在 80Bits 的 bit48-42(0000000 表 1900 年、1111111表 2027 年)。 4. 婚姻放在 80Bits 的 bit49(0 表未婚、1 表已婚)。 5. 學歷放在 80Bits 的 bit52-50(000 表博士、111 表未知)。 6. 手機號碼只紀錄 09 開頭的號碼(09XXXXXXXX),存放在 80Bits 的 bit79-53,手機號碼 0930093093 能表示成 001110010110010111100100101。 ![image alt](https://cdn.discordapp.com/attachments/592247718194184213/596209588928512010/unknown.png) 7. 有一個人資料:身分證字號 M159746147、出生年月日 1958 年 05 月 28 日、已婚、學歷是博士、手機號碼為 0930093093,經編碼後的 10 Bytes 資料以十六進制表示為 3965E4A2E978C38FA763,如下左圖。【10 分】 ![image alt](https://media.discordapp.net/attachments/592247718194184213/596209775990276097/unknown.png) 8. 有一個人資料的 10 Bytes 資料以十六進制表示為 361499DD933F8DDC24AD,經解碼後的詳細個人資料如上右圖。【8 分】 ## 解題想法 這題應該是競賽內很麻煩的水題了。 ※水題:按圖施工的題目、或者解法極為直觀以致於不用思考就能開始解。 處理資料上比較麻煩,換身分證字號時我們可以用內建函數String.Substring(int index) 來取我們從第index個字元到最後一個字元的子字串,或者String.Substring(int index,int length)來取從第index個字元到第index+length個字元的子字串。 ```csharp= String str = "abcdef"; String subString1 = str.Substring(1); //bcdef String subString2 = str.Substring(1,2); //bc ``` 至於往左補零到指定位數,我們可以使用String.padLeft(int totalWidth, char paddingChar)來做往左補零的動作。 ```csharp= String str = "10010"; String padLeftString = str.padLeft(7,'0'); //0010010 String padRightString = str.padRight(7,'0'); //1001000 ``` 接下來,關於身分證開頭字元的部分,我們可以先轉成ACSII Code然後再做處理。 剩下的大致上是按圖施工,除了轉換學歷與婚姻時,假設Control包含了多個Item(例如ListBox可以包含了許多的Item,婚姻與學歷所使用的comboBox包含了許多的Item),而我們要尋找這個字串在Control的哪個Item,我們可以使用ControlBox.ObjectCollection.IndexOf(object value)來做搜尋index的動作。 那麼,假設我們要取在ControlBox的第i項的字串,則我們可以使用ControlBox.ObjectCollecton[i]來做搜尋的動作。 ```csharp= //有一個comboBox,內部有已婚與未婚的Item,未婚是第一個選項,已婚是第二個選項 int index = ComboBox1.Items.indexOf("未婚"); //index = 0 String item = ComboBox1.Items[index].ToString() //item = "未婚"; ``` 麻煩讀者詳細閱讀以下的程式碼,再多加對照。 ## 程式碼(C#) ```csharp= using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace problemA { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { } public string converter(string str) { string result = ""; for(int i = 0; i < 20; i++) { result += Convert.ToString(Convert.ToInt16(str.Substring(4 * i, 4),2),16); } return result; } private void button1_Click(object sender, EventArgs e) { string result1 = ""; string result2 = ""; string result3 = ""; string result4 = ""; string data1 = textBox1.Text; string data2 = textBox2.Text; string data3 = comboBox1.Text; string data4 = comboBox2.Text; string data5 = textBox3.Text; result1 = Convert.ToString(Convert.ToInt64(data1.Substring(2)),2).PadLeft(27,'0'); result1 = (data1[1].Equals('1') ? '0' : '1') + result1; result1 = Convert.ToString(0 + (data1[0] - 'A'), 2).PadLeft(5,'0')+ result1; result1.PadLeft(32, '0'); string year = Convert.ToString(Convert.ToInt16(data2.Substring(0, 4)) - 1900, 2).PadLeft(7,'0'); string month = Convert.ToString(Convert.ToInt16(data2.Substring(4, 2)),2).PadLeft(4,'0'); string day = Convert.ToString(Convert.ToInt16(data2.Substring(6, 2)), 2).PadLeft(5, '0'); result2 = year + month + day; result2 = comboBox1.Items.IndexOf(data3) + result2; result3 = Convert.ToString(comboBox2.Items.IndexOf(data4),2).PadLeft(3,'0'); result4 = Convert.ToString(Convert.ToInt32(data5.Substring(2)),2).PadLeft(27,'0'); string result = result4 + " " + result3 + " " + result2 + " " + result1; Console.WriteLine(result); textBox4.Text = converter(result.Replace(" ","")).ToUpper(); } private void button2_Click(object sender, EventArgs e) { string data = textBox4.Text; string str = ""; for(int i = 0; i < data.Length; i++) { str += Convert.ToString(Convert.ToInt16(data[i].ToString(),16),2).PadLeft(4,'0'); } Console.WriteLine(str); string phoneNumber = "09" + Convert.ToInt32(str.Substring(0, 27),2); string study = comboBox2.Items[Convert.ToInt32(str.Substring(27, 3), 2)].ToString(); string married = comboBox1.Items[Convert.ToInt32(str[30].ToString(), 2)].ToString(); string year = (Convert.ToInt32(str.Substring(31, 7), 2) + 1900).ToString(); string month = Convert.ToInt32(str.Substring(38, 4), 2).ToString().PadLeft(2,'0'); string day = Convert.ToInt32(str.Substring(42, 5), 2).ToString().PadLeft(2, '0'); string word = "" + ((char)(Convert.ToInt32(str.Substring(47, 5), 2) + 'A')).ToString(); string number1 = (Convert.ToInt32(str.Substring(52, 1), 2)+1).ToString(); string number2 = (Convert.ToInt32(str.Substring(53),2)).ToString(); textBox1.Text = word + number1 + number2; textBox2.Text = year + month + day; comboBox2.Text = study; textBox3.Text = phoneNumber; comboBox1.Text = married; } } } ```