選單

各國證件號的校驗規則為什麼統一不了

各國證件號的公開程度差很多:有的公布校驗位演算法,有的只公布格式,有的連完整說明都不公開。本文說明這三類制度該怎麼分別處理,以及為什麼不能讓工具替使用者猜一個國家。

發佈於

  • 證件號
  • 跨國表單

同樣是身分證件號,有的國家把它設計成可以自我檢查的字串,有的只規定長度與可用字元,還有的連完整的格式說明都不對外公開。本文說明為什麼各國證件號的校驗規則統一不了,這三類制度分別該怎麼處理,以及為什麼好的工具會並列候選制度,而不是替使用者選一個國家。

各國證件號為什麼不能統一校驗?

因為校驗從來不是一個國際共通的機制,而是各國自己的登記制度在設計時順帶加上去的性質。有的制度重視防錯,於是在編號裡留一位由其餘位算出的校驗位;有的制度只在意流水號的分配,於是就沒有這一層。

這不是誰做得比較好,而是設計目標不同。一旦接受這個前提,就會發現「用一套規則驗所有國家的證件號」在邏輯上並不成立。你能統一的只有介面與流程,規則本身必須逐國看待。

還有一層差異是公開程度。即使某個制度內部有校驗規則,只要它沒有對外公布,外部實作者就只能做到格式層級。把「我算不出來」講成「這個號碼無效」,等於把工具的限制說成使用者的錯誤。

還有一個常被忽略的面向是歷史。編號規則會改版,舊號碼不會因此失效,於是同一個欄位在不同年份核發的號碼可能落在不同的規則之下。實作時若只依最新一版規則判斷,就會把一批仍然有效的舊號碼判成錯誤。比較穩健的做法是讓規則帶上生效期間,而不是只留一份最新版本。

有公布校驗位演算法的制度

這類制度把校驗位怎麼算寫在公開說明裡,因此外部系統可以在離線狀態下判斷一個號碼是否自洽。它們的共同特徵是:位數固定或有明確範圍、可用字元集有清楚定義、校驗位由其餘位決定。

處理這類制度時,重點是照公布的方式實作,並用官方樣本自檢。不要因為它與你熟悉的另一支算法長得像,就套用自己手上的那組參數。前一位算錯,整串的結論就會相反。

另外要記得,這一類制度的數量不代表多數。同樣是國際化的系統,遇到的大多數證件號欄位其實落在另外兩類,只是因為前兩者比較好處理,討論時容易被放大。

只有格式、沒有公開演算法的制度

第二類制度公布了格式,但沒有公布可以用來計算的校驗方式。可能是長度與字元集有明文規定,也可能只有一份簡略的說明。這時能做的只有格式層級的確認。

這一類的結論必須誠實標成「僅格式」。它與「校驗通過」是完全不同的兩件事:前者說的是工具沒有規則可算,後者說的是工具算了而且成立。把兩者混用,會讓使用者對系統的能力產生錯誤期待。

需要特別提醒的是,不能因為別的國家有校驗位,就推斷某個制度「應該也有」。這種推斷在跨國表單裡非常常見,也正是最多誤判的來源。

這一類制度還有一個容易出錯的地方:格式的說明本身也可能只公開一部分。例如長度寫明了,可用字元集卻只有範例。這時實作者往往會從範例反推規則,而反推出來的規則通常比實際更嚴格,於是合法的輸入被擋在門外。遇到這種情況,寧可放寬到只確認長度,也不要憑範例收緊。

一個號碼同時對上多個國家時怎麼辦?

同一個字串同時滿足兩個以上國家的規則,並不少見。長度、字元集與校驗方式都有可能剛好對上,而這並不是錯誤,而是兩句各自為真的敘述。

比較好的做法是把所有吻合的候選制度並列,讓使用者依實際情境自己選,或者讓上層流程依表單欄位的用途決定。工具不該替使用者猜一個國家,因為猜錯會把合法的號碼標成失敗。

並列還有助於解釋。當使用者問「為什麼說我的號碼有問題」,你可以回答「因為在你選定的制度下校驗位不成立」,而不是含糊地說「系統不接受」。這種可解釋性正是分態結論的價值所在。

長度與字元集只是起點

把長度對、字元集對當成「號碼有效」,是這類系統最常見的誤判。長度只是一道門檻,它擋掉的是明顯的輸入錯誤,不是偽造或不存在的號碼。

真正容易出事的場合是國際化的表單:欄位長度上限依某一國設定,其他國家的號碼就被截斷;只允許數字的欄位收到含字母的號碼,就被判成格式錯誤。這些都不是號碼的問題,而是欄位設計的問題。

務實的做法是把長度與字元集當成可調整的資料,而不是散在驗證邏輯裡的字面值。規則一旦調整,改資料比改流程安全得多。

另一個常見的坑是正規化的時機。若在輸入當下就大寫轉換或去除符號,而使用者之後才發現貼錯了來源,畫面上的值已經與原始輸入不同,除錯會變得很困難。比較好的做法是保留原始輸入,另外存一份正規化後的值,兩者一起記錄。

給開發者:把國家規則做成資料

面對逐國不同的規則,硬編碼是最快也最貴的做法。比較穩定的結構是把每個制度描述成一筆資料,欄位大致如下:

  • 制度代號與所屬國家或地區。
  • 允許的長度範圍與字元集。
  • 是否有公開的校驗位演算法;若有,指向對應的參數描述。
  • 額外的排除條件,例如特定序列不受理。
  • 對應的官方說明來源,方便日後核對。
  • 規則的生效期間與版本,方便解釋歷史資料的判定結果。

有了這份描述,驗證流程就只剩下「查規則、跑檢查、組結論」三步。新增一個國家是加一筆資料,調整規則也只動那一筆。校驗失敗時要能說出依據是哪一筆的哪一條,使用者才有辦法修。

還有一件事值得先做:把每一筆規則的來源連結記在同一份表格裡。日後有人質疑判定結果時,你能直接把公布說明貼給他看,而不是回頭翻半年前的討論紀錄。

下一步

先盤點你系統裡所有收證件號的欄位,把它們目前假設的長度與字元集寫下來,逐項確認那些假設來自哪一個制度的公布說明。接著把其中一個欄位改成「先分流、再檢查」的結構,並用號碼校驗工具觀察同一個字串在不同候選制度下會得到哪些結論。沒有公開演算法的制度該怎麼標示,可以接著讀沒有校驗位的號碼;兩種稅號並存的例子讀CPF 與 CNPJ 校驗。

本文不針對任何國家的真實證件號規則舉例;出現的字串都是構造值,只用來對照三種公開程度不同的制度,不構成任何身分證明。

繼續閱讀

卡號與身分證號校驗工具相關文章