# 北軟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。

7. 有一個人資料:身分證字號 M159746147、出生年月日 1958 年 05 月 28 日、已婚、學歷是博士、手機號碼為 0930093093,經編碼後的 10 Bytes 資料以十六進制表示為 3965E4A2E978C38FA763,如下左圖。【10 分】

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;
}
}
}
```