M1 卡的儲存容量為 1024 位元組,分成 16 個區段 (Sector),每個區段分成 4 個區塊 (Block),每個區塊有 16 位元組,每次讀寫都是以區塊為單位。卡號被存在第 0 區塊,然後在每個區段的最後一個區塊會儲存兩個金鑰 A/B 以及存取權限。
M1 卡的製造商區塊位於第 0 區塊,在卡片被製造時會被寫入製造商的資料,這個區塊是唯讀無法被修改的,以下分別是 4 位元組卡號以及 7 位元組卡號的資料格式:
製造商區塊內除了卡號之外,大多數的魔術卡會把防碰撞的資料也存在製造商區塊內,以便讓你可以修改防碰撞的資料:
在 M1 魔術卡 4 位元組卡號的製造商區塊中,有一個 BCC 的欄位,這個欄位是用來驗證卡號的正確性,其計算公式為:
// ^ 是 XOR 運算子
BCC = UID0 ^ UID1 ^ UID2 ^ UID3
除了區段 0 只有兩個資料區塊以外,其他區段的前三個區塊 Block 是資料區塊,可透過區段的「存取控制位元」設定區塊的讀寫權限以及「值區塊」的相關權限。
只要把一個特殊的格式寫入到「資料區塊」,這個區塊就可以當成「值區塊」來使用。「值區塊」除了一般的讀寫操作之外,還支援額外的加值 (increment)、減值 (decrement)、還原 (restore)、轉存 (transfer) 指令,通常會被用來儲存電子錢包的餘額。
「值區塊」的資料格式包含兩個資料,資料會被重複儲存以便用來錯誤偵測、修正以及備份:
value
:4 個位元組的有號整數,以 little endian 格式儲存在 byte 0-3 以及 byte 8-11,然後把資料進行 2 進位補數後儲存在 byte 4-7。adr
:1 個位元組的無號整數,儲存在 byte 12 及 14,然後把資料進行 2 進位反相後儲存於 byte 13 及 15。可用來紀錄這個值區域是哪個值區域的備份,在進行值區域的專屬操作時 (increment、decrement、restore、transfer),都不會修改這個值,這個值只能透過寫入操作來修改。下圖是值區塊的資料格式,以及一個以 value = 0x0012D687, adr = 0x11
為例的值區塊:
區段尾端是指每個區段中的第四個區塊 (block 3),這個區塊儲存該區段的 Key A、Key B (選擇性) 及存取權限 (ACL)。
如果不使用 Key B 也可以把這 6 個位元組拿來儲存一般資料(需要設定相對應的存取權限)。
區段尾端區塊的 byte 6-8 是用來紀錄存取權限,byte 9 可以用來儲存資料,存取權限跟 byte 6-8 相同,Key A 在讀取時只會回傳 6 個位元組的 0x00
,如果 Key B 設定成不可讀取時,同樣會在讀取時回傳 6 個位元組的 0x00
。