寫在前面
第八週實驗報告的deadline馬上就要到了,大家都在奮筆疾書。這次的實驗報告中有一個十分禿然的任務,要求學生用C語言編寫一段程式碼,來處理編碼問題。
我的ddl是在第七週,所以較早地解決了這個問題。但解決過程也是十分的禿然。鑑此,我決定分享一下這個任務的解決經驗,希望給予需要的同學一點微薄的幫助。
索引
- 寫在前面
- EM卡韋根32/24格式卡號轉換的實現
- 1.1 問題概述
- 1.2 EM卡的ID格式
- 1.3 規劃卡號轉換思路
- 1.4 程式碼實現
- 寫在最後
注:本篇文章中的所有圖片均新增了title屬性,可將滑鼠放置在圖片上檢視懸浮資訊。
EM卡韋根32/24格式卡號轉換的實現
1.1 問題概述
這個問題大概長這個樣子:
使用C語言程式語句來描述,EM4110卡面上三個資料間轉換。額外引入一個運算元,通過C語言運算操作符實現。
看完問題,我們大概瞭解到,要想解決問題,首先要弄清EM卡上的資料是什麼樣子的。
1.2 EM卡的ID格式
這是一張EM4110卡:
EM卡是一種ID卡,其內部儲存了卡內序列號(十六進位制)。我們已知這張卡的卡內序列號為 19 00 6D 30 F4 .
我們觀察到,卡面上噴印了一段序列號:0007155956 109, 12532 。卡面序列號和卡內序列號又有什麼關係呢?通過計算,我們可以得出下述關係:
- 卡內序列號
以序列 19 00 6D 30 F4 為例,19 為廠商程式碼,00 為固定位,6D 30 F4 可以根據韋根32/24格式轉換成卡面序列號。 - 前段序列
前段序列是韋根32格式卡號,它是將十六進位制的卡內序列號 19 00 6D 30 F4 中的後8位 00 6D 30 F4 ,經數制轉換後得到10位十進位制資料(不足10位在首位補0). - 後段序列
後段ID是韋根24格式卡號,它是將十六進位制的卡內序列號中的後6位,按照“2+4”的格式分成兩段十進位制資料,兩段資料間用“,”隔開。
例如:卡內序列號後6位為 6D 30 F4 ,則對應的後段卡號為 6D, 30 F4,即 109, 12532.
瞭解了韋根32/24格式卡號的原理後,我們開始解決卡號轉換的問題。
1.3 規劃卡號轉換思路
按照 1.2 EM卡的ID格式 中的內容,我們可以畫出流程圖:
graph TD
Begin("begin") --> Input["input Operand"] --> Switch{"Operand?"}
Switch --> |"Operand = 0"| W32To24_Input["input Wiegand32"]
W32To24_Input --> W32To24_Handle1["Wiegand24_1 = Wiegand32 >> 16"]
W32To24_Handle1 --> W32To24_Handle2["Wiegand24_2 = (Wiegand32 << 16) >> 16"]
W32To24_Handle2 --> Output
Switch -->|"Operand = 1"| W24To32_Input["input Wiegand24"]
W24To32_Input --> W24To32_Handle1["Wiegand32 = Wiegand24_1 << 16 | Wiegand 24_2"]
W24To32_Handle1 --> W24To32_Handle2["Wiegand24_1 >> 16"]
W24To32_Handle2 --> Output
Switch -->|"Operand = -1"| End
Output["output Wiegand32 Wiegand24_1, Wiegand24_2"] --> End("end")
考慮到進位制轉換問題,這裡使用位運算可以簡化我們對數的操作。
下面對位運算語句進行解釋:
- Wiegand24_1 = Wiegand32 >> 16
如圖,將 Wiegand32 右移16位,得到 Wiegand24_1 後段序列第一部分。
- Wiegand24_2 = (Wiegand32 << 16) >> 16
如圖,先將 Wiegand32 左移16位,消掉 30 ,得到的結果再右移16為,即為 Wiegand24_2 後段序列第二部分。
- Wiegand32 = Wiegand24_1 << 16 | Wiegand 24_2
如圖,將左移16位的 Wiegand24_1 與 Wiegand 24_2 進行或運算,得到 Wiegand32 前段序列。
- Wiegand24_1 >> 16
如上圖,對 Wiegand24_1 左移16位後,應將其移回初始位元位,以便輸出結果。
1.4 程式碼實現
看到這裡,相信大家也能夠獨立實現程式碼的編寫了。下面我提供一種實現方法:
#include<stdio.h>
int main()
{
int operand;
int w32, w24_1, w24_2;
printf("----------------------------------\n\n");
printf(" 0\tWeiGE 32 -> WeiGE 32/24\n");
printf(" 1\tWeiGE 24 -> WeiGE 32/24\n");
printf(" -1\tExit\n");
printf("\n----------------------------------\n");
while (operand != -1)
{
printf(">> Please enter command: ");
scanf("%d", &operand);
if (operand == 0)
{
printf(">> Please enter WeiGE 32: ");
scanf("%d", &w32);
w24_1 = w32 >> 16;
w24_2 = (w32 << 16) >> 16;
printf(">> WeiGE 32/24: ");
printf("%010d %d,%d\n", w32, w24_1, w24_2);
}
else if (operand == 1)
{
printf(">> Please enter WeiGE 24: ");
scanf("%d,%d", &w24_1, &w24_2);
w32 = w24_1 << 16 | w24_2;
w24_1 >> 16;
printf(">> WeiGE 32/24: ");
printf("%010d %d,%d\n", w32, w24_1, w24_2);
}
}
return 0;
}
這段程式碼根據要求額外新增了運算元系統,可根據提示資訊來選擇操作模式,大家也可以上手體驗一下。
寫在最後
源心鎖學長在去年也寫了一篇關於EM卡號轉換的文章,本文末程式碼的思路也和學長的思路大致相同,在此膜拜一下大佬。
終於趕在五一放假前敲完了這篇文章,實驗人去肝報告了,沒有時間排版......
最後祝大家假期快樂~