【C】EM卡韋根32/24格式卡號轉換的實現

是阿夢呀發表於2021-04-29

寫在前面

第八週實驗報告的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卡號轉換的文章,本文末程式碼的思路也和學長的思路大致相同,在此膜拜一下大佬。
終於趕在五一放假前敲完了這篇文章,實驗人去肝報告了,沒有時間排版......
最後祝大家假期快樂~

相關文章