各國身份證號長度不是統一的規格,而是各國行政制度長期累積的結果:有的國家只用數字,有的混用字母,有的把出生日期直接編進號碼,也有的在最後放一兩位校驗位。以下說明這些差異從哪裡來、對錶單與資料庫設計造成什麼影響,以及遇到不熟悉的格式時該怎麼處理。
長度能不能當成判斷國家的線索?
不能,最多只能當成弱線索。同一個長度可能同時對應好幾個國家,而一個國家內部也可能同時存在新舊兩種格式。把長度寫成國家的判別條件,等於把一個會變動的慣例當成規則,日後只要有一個國家改版,整段邏輯就要重寫。
比較穩健的關係是反過來:國家決定可接受的格式,格式再由發行的機構維護。程式需要知道的是「這個國家允許哪些形狀」,而不是「某個形狀一定是哪個國家」。
還有一個實務上的理由:使用者可能持有多個國家的證件,或在一筆紀錄裡同時提供兩個國家的資料。此時長度只能告訴你「這串字元可能是什麼」,真正決定要用哪一套規則的,是使用者選擇的發行國家。
純數字、字母混合與校驗位的差別
這三種設計面對的是不同的問題。純數字的優點是容易輸入、容易在紙本上抄寫,缺點是同樣位數能容納的組合較少。加入字母可以擴大容量,代價是使用者容易混淆形似的字元,例如數字一與字母 I、數字零與字母 O。
校驗位解決的是手誤。它用一個簡單的算術關係,讓打錯一個字或把相鄰兩位寫反的號碼在檢查時被發現。常見的做法是加權求和之後取餘數,把結果放在最後一位或最後兩位。
| 設計 | 主要目的 | 常見副作用 |
|---|---|---|
| 純數字 | 容易輸入與抄寫 | 位數偏長才能容納足夠組合 |
| 字母混合 | 擴大可用組合 | 形似字元容易互換 |
| 帶校驗位 | 攔下手誤與順序顛倒 | 實作錯誤時會誤擋合法號碼 |
| 內含出生日期 | 讓號碼攜帶基本資訊 | 改版時最難相容 |
要注意的是,校驗位只能證明「這串字元符合規則」,不能證明「它屬於某個人」。一組通過校驗的合成號碼同樣可能對應到真實存在的人,因此通過檢查並不代表可以用於任何真實身分相關的用途。
校驗位算錯會發生什麼事?
校驗位的價值全部建立在演算法正確上。若實作時用了錯的權重、把餘數的處理寫反,或把字元對應的數值表抄錯,結果就是一批合法的號碼被擋下,而不合法的號碼反而通過。這種錯誤不會讓程式崩潰,只會讓某個國家的使用者特別容易卡住。
驗證時可以先用人工算過的幾組樣本確認演算法,再放入刻意改動一位的樣本,確認系統能分辨「長度對但校驗錯」與「長度本身就不對」。兩者的提示應該不同,因為使用者能採取的行動不同。
為什麼同一個國家也可能換過格式?
行政機關會調整編碼方式,理由可能是位數不夠用、需要加入新的行政區、或是要汰換舊的核發流程。改版之後通常會有一段並行期,新舊號碼同時有效,於是驗證邏輯必須同時接受兩種形狀。
美國的社會安全號碼就是一個例子:2011 年起改為隨機分配,號碼裡的數字不再表示發放地點或時間。巴西的個人稅號是十一位,最後兩位是校驗位;加拿大的社會保險號碼是九位。這幾個例子剛好說明了同一件事:長度、字元集與校驗方式都可以各自獨立變化,不能只看其中一項。
對測試的啟示是,樣本裡應該刻意放入同一國家的兩種格式,看看系統在舊格式仍然有效的情況下會不會誤擋。這種情況在真實資料裡一定會出現,只是什麼時候出現而已。
各國制度的粗略分類
如果要把制度歸類,大致可以分成幾種取向:
- 以數字為主的制度,長度固定,規則簡單,通常只在最後加校驗位。
- 字母數字混合的制度,長度可能固定或不固定,允許的字母範圍另有規定。
- 把出生日期編進號碼的制度,北歐國家的個人身份號碼屬於這一類,因此號碼本身帶有時間資訊。
- 由多段組成的制度,不同段各自代表不同的行政資訊,整串必須一起解讀才成立。
這幾類對應的驗證工作完全不同。數字為主的制度適合用長度加校驗位把關;混合制度還要處理大小寫與允許字元的問題;內含日期的制度則會多出一個麻煩:日期本身可能是無效的,例如把二月三十日編進去。
分類的用途不在於精確,而在於提醒自己規則有幾種來源。當你寫下第一條「所有號碼都是數字」的假設時,就已經決定了未來要為多少例外重寫程式。
給開發者:欄位長度不要寫死
- 儲存時一律當成文字,不要轉成數字,前導零與字母都不能遺失。
- 長度用範圍或規則描述,不要用單一固定值。
- 按發行國家切換驗證,而不是用一條通用規則套用所有國家。
- 保留「未知格式」的兜底分支,讓沒見過的國家仍然可以存、可以顯示。
- 大小寫與分隔符號在比對前先正規化,但保存原始輸入以便顯示。
- 需要測試拒絕邏輯時,刻意放入長度差一位、校驗位錯誤與無效日期的樣本。
本站的身份產生器可以切換國家產生證件號,同一筆紀錄的姓名、地址與出生日期都彼此對應;這些內容只供測試,不能拿來冒充真人,也不能作為任何真實身分的證明。若要檢查這類欄位與其他欄位是否互相矛盾,可參考身份資料一致性。
遇到不認識的格式該怎麼辦?
先讓它通過,再把資訊記下來。對一個不熟悉的國家直接拒絕,代價是使用者無法完成流程;而接受之後沒有留下紀錄,就永遠不知道有多少人卡在這裡。實務上的折衷是:格式未知時允許儲存、允許顯示,但標記為未驗證,並在統計上追蹤。
另一個原則是不要把驗證結果當成事實宣告。系統能判斷的是「這串字元符合某個形狀」,不是「這個人真的住在這裡」。把這兩件事混在一起,最後就會寫出既擋掉合法輸入、又給出錯誤安全感的規則。
下一步
挑三個你支援的國家,把這三種情況各跑一遍:合法號碼、長度差一位、校驗位錯誤,看看系統的提示是否分得出來。若你正在準備跨國樣本,先讀測試身份資料是什麼,再回到本站工具產生幾組不同國家的紀錄來比對。
另外,別忘了把驗證結果寫進紀錄。當某個國家的失敗率特別高,那個數字通常是規則寫錯的第一個線索,而不是使用者集體打錯字。