身分證字號十碼,前九碼帶身分資訊,只有最後一碼是拿來自我檢查的。它不是流水號的一部分,而是由前面九碼算出來的補數。知道這件事以後,很多誤會會自己解開:為什麼線上工具能「驗證」身分證、為什麼驗過了還是證明不了這個人存在,以及產生器到底在產什麼。
會想做身分證字號驗證這支工具,其實是小時候的記憶。以前辦遊戲帳號常常要填身分證字號,我很常用網路上的身分證製造機湊一組過關。長大寫程式才知道那些製造機在做的事只有一件:湊出一串讓檢查碼成立的字元。這篇就是把那件事拆開來講。
第一步:字母先變成兩位數
開頭的縣市字母要先換成兩位數。A 是 10、B 是 11,照字母序往下排,但有幾個位置不照順序:I 是 34、O 是 35,尾端的 W=32、X=30、Y=31、Z=33 也跳過。這張表沒有公式可推,所以我在工具裡是寫死一份對照表。字母代表的是初次設籍的縣市,不是現在的住址,搬家不會改;L、R、S 對應的台中縣、台南縣、高雄縣已經併入直轄市,Y 是早年的陽明山管理局,這些歷史代碼驗證時照收,不能因為「這個縣市已經不存在」就判錯。
第二步:加權相乘,總和除 10
字母拆成十位與個位之後,整串號碼展開成 11 個數字,對上權重序列 [1, 9, 8, 7, 6, 5, 4, 3, 2, 1, 1],乘完加總,總和能被 10 整除就通過。拿 F123456784 走一次(這組是我用站上產生器產的測試號,不是任何人的證號):
| 位置 | 數字 | 權重 | 乘積 |
|---|---|---|---|
| F → 15 的十位 | 1 | 1 | 1 |
| F → 15 的個位 | 5 | 9 | 45 |
| 第 2 碼 1 | 1 | 8 | 8 |
| 第 3 碼 2 | 2 | 7 | 14 |
| 第 4 碼 3 | 3 | 6 | 18 |
| 第 5 碼 4 | 4 | 5 | 20 |
| 第 6 碼 5 | 5 | 4 | 20 |
| 第 7 碼 6 | 6 | 3 | 18 |
| 第 8 碼 7 | 7 | 2 | 14 |
| 第 9 碼 8 | 8 | 1 | 8 |
| 第 10 碼 4(檢查碼) | 4 | 1 | 4 |
| 總和 | 170 | ||
170 除以 10 餘 0,通過。把最後一碼蓋掉再看一次:前十項的和是 166,個位是 6,所以檢查碼只能是 4。產生器做的就是這件事,前九碼隨機湊,最後用「(10 − 總和 mod 10) mod 10」補上檢查碼。它沒有翻過任何名冊,也沒有名冊可翻。
居留證:舊式兩個字母,新式跟身分證同格式
外來人口統一證號(居留證號)2021 年改過版,新舊兩式現在並行。同一個欄位如果只認新式,會把持舊證的人直接擋在門外:
| 項目 | 舊式 | 新式(110/1/2 起) |
|---|---|---|
| 整體格式 | 2 個英文字母 + 8 個數字 | 1 個字母 + 9 個數字(與國民身分證同格式) |
| 第 1 碼 | 區域碼,同身分證的縣市字母 | 區域碼,同身分證的縣市字母 |
| 第 2 碼 | A–D:A 男 B 女(無戶籍國民、大陸、港澳)、C 男 D 女(外國人、無國籍) | 8 = 男、9 = 女 |
| 第 3 碼 | 流水號的一部分 | 身分碼:0–6 外國人及無國籍、7 無戶籍國民、8 港澳居民、9 大陸地區人民 |
| 檢查碼 | 同身分證算法,但第 2 碼字母轉數字後只取個位、權重 8 | 與國民身分證完全相同 |
| 適用期間 | 至 119/12/31 仍有效,120/1/1 起停止適用 | 110/1/2 起核發 |
新式的檢查碼跟國民身分證同一套,銀行、電商、政府系統從此能共用同一段驗證邏輯。舊式的第 2 碼是字母,轉成數字後只取個位、權重 8,其餘完全一樣。我在工具的測試裡把移民署公告的範例號碼 A800000014 釘成錨點,因為這頁上線初期真的出過錯:把不存在的 6/7 當成新式的性別碼、又把真正的 8/9 標成舊式。那種錯誤肉眼看不出來,只有錨點測試擋得住。
我自己沒踩過這個坑,但寫驗證的時候有幾個地方值得檢查。第 2 碼只允許 1、2 的正規表示式會把新式統一證號整批擋掉;舊式的第 2 碼是字母,用純數字欄位存會存不進去。兩種都是十碼,長度通常不是問題,問題在字元集。移民署公告的並行期間內兩種號碼都會出現,驗證要同時收,期限以官方公告為準。
檢查碼過了,不代表這個人存在
這是整篇最重要的一段。檢查碼通過只代表這串字元符合公開的編碼規則,工具沒有去任何資料庫查,也沒有資料庫可查——戶政不會公開已發號碼的清單,也不該公開。所以「格式合法」「檢查碼正確」「這張證件真的存在」是三層,任何線上工具都只做得到前兩層,要確認真偽只能循主管機關的查驗管道。
標題說產生器不會撞到真人,精確一點講是這樣:號碼本身不帶任何可辨識的個人資料。身分證字號不含出生年月日,第 3 到 9 碼是流水號、沒有規則可逆推,字母只說得出初次設籍的縣市。所以一串隨機湊出來、剛好讓檢查碼成立的字元,跟某個真人的證號字面相同與否,工具無從得知也無從避免;但它不指向任何人,因為要把號碼對到人,必須有戶政系統,這頁沒有。這也是為什麼產生的號碼只能拿去填測試表單,拿去申辦、開戶、投保都可能觸法。
反過來,你貼進來要驗的那組號碼也一樣不會留下。驗證與產生都在瀏覽器裡跑完,本站沒有任何後端收得到它;頁面另外對錄影分析工具遮蔽輸入內容,分析只記得「有人複製了一次、產生了一次」。
這支工具做不到的事
- 不能告訴你這組號碼有沒有真的核發給誰。
- 不能查姓名、住址或任何個人資料,只處理號碼本身。
- 不能反推出生年份,身分證字號裡根本沒放。
- 健保卡號(12 碼)與護照號碼(9 碼純數字,或晶片護照的 1 字母 + 8 碼)只做格式檢查。健保署與外交部都沒有公開檢查碼演算法,格式對只代表「長得像」。
順帶一提,另外兩套檢查碼
統一編號是 8 碼,權重 [1, 2, 1, 2, 1, 2, 4, 1],乘積滿 10 要把十位跟個位相加再計入。重點是 112 年 4 月起檢查條件從「可被 10 整除」改成「可被 5 整除」,原因是舊號預估 113 年用罄、要擴增號碼空間;新制與舊號完全相容,但沒跟上的舊系統會把新號判成錯的。財政部修正說明附件的範例 04595252、10458570 都是新制才有效,拿這兩組測自家程式最準。另外第 7 碼是 7 的時候有個加一的特例,兩種實作差 1,工具兩種都收。
台灣居民居住證是 18 碼,沿用中國大陸的公民身份號碼規則(GB 11643-1999):台灣居民地址碼固定 830000、第 7 到 14 碼是出生年月日、第 17 碼奇數男偶數女,檢查碼走 ISO 7064 MOD 11-2,算出 10 的時候寫成 X。跟台灣身分證相反,這組號碼讀得出生日與性別。至於卡式台胞證的 8 碼,主管機關沒有公開任何檢查碼規則,所以只能驗格式——網路上宣稱能驗台胞證「合法性」的工具,都是唬的。
資料來源
- 新舊統一證號格式、身分碼、性別碼與並行期間:內政部移民署公告的「外來人口統一證號格式說明」。
- 國民身分證字號的編配與縣市代碼:主管機關為內政部戶政司。
- 統一編號檢查碼由除 10 改為除 5:財政部財政資訊中心「營利事業統一編號檢查碼邏輯修正說明」。
- 健保卡號規定見衛生福利部中央健康保險署、護照號碼樣式見外交部領事事務局,兩者皆未公開檢查碼演算法。
- 格式與適用期限都可能調整,一律以主管機關最新公告為準;個案請洽各該機關。
