---
# System prepended metadata

title: 北軟96 pA 10Bytes編解碼程式
tags: [北軟96]

---

# 北軟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;
        }
    }
}

```