資料輸入時,長度對、字母與數字對,仍可能把尾碼打錯。這次把國民身分證編號的校驗拆成六個看得見的步驟,讓你知道錯在格式、轉碼,還是最後的檢查碼。
本篇只處理樣式與檢查碼。 通過並不代表號碼真的核發、仍有效、屬於填寫者,或能驗證任何人的身分。所有例子由演算法合成,沒有連到姓名、帳號或真實個人,也不查詢任何身分資料。
本例範圍是:一個英文字母、第二碼為 1 或 2,接著八個數字。不包含居留證、新式統一證號等其他證件;不要將不同證件一起丟進同一條規則。
準備原始輸入與六欄結果
在空白工作表的 A1:G1 填入:
| 原始輸入 | 標準化 | 格式 | 字母轉碼 | 加權和 | 應有尾碼 | 檢核結果 |
|---|
以下全是本篇合成例,依位置填入 A2:A18:
| 位置 | 輸入 | 用途 |
|---|---|---|
A2 | A100000001 | 演算法合成,首字母A |
A3 | A200000003 | 演算法合成,第二碼2 |
A4 | A100000010 | 演算法合成,檢查碼0 |
A5 | I100000003 | 演算法合成,非順序字母映射I |
A6 | O100000004 | 演算法合成,非順序字母映射O |
A7 | W100000001 | 演算法合成,非順序字母映射W |
A8 | Z100000002 | 演算法合成,非順序字母映射Z |
A9 | A100000002 | 只改合成尾碼 |
A10 | a100000001 | 小寫與前後半形空白清理 |
A11 | 留空 | 空白 |
A12 | A300000000 | 第二碼不在本例範圍 |
A13 | 100000001 | 缺英文字母 |
A14 | A100000001 | 全形字母不自動正規化 |
A15 | A100000001 | 全形數字不自動正規化 |
A16 | A1 00000001 | 中間空白 |
A17 | AB00000000 | 舊式證號非本例 |
A18 | 1234567890 | 純數字不是格式 |
A10 是清理測例:在小寫 a100000001 前後各加兩個半形空白。A11 保持真正空白。全形字母、全形數字與中間空白則故意保留,觀察格式檢查是否擋下。
保留原始輸入的 A 欄,不直接覆蓋它。這樣才看得出清理前後改了什麼。
第一步:統一大小寫與前後半形空白
在 B2 輸入:
保留原值,另欄產生本例採用的標準化文字
=UPPER(TRIM(A2))這裡的政策是接受小寫英文字母,並清除前後半形空白。格式欄接著檢查的是標準化後的內容,不代表原始輸入本來就符合規定。
本例沒有做全形字母/數字轉換,也沒有刪除中間空白;遇到它們會要求回頭核對原值,不默默猜測想輸入什麼。
第二步:先確認格式,再做數字運算
在 C2 輸入:
只接受本例的國民身分證編號樣式
=REGEXMATCH(B2,"^[A-Z][12][0-9]{8}$")TRUE 代表標準化後符合這個樣式,FALSE 代表不符合。這時還沒有檢查尾碼,不能把 TRUE 命名成「身分有效」。
先擋下格式錯誤,後面的公式才不會把字母、空格或全形數字硬轉成數值。
第三步:放入官方字母轉碼表
在 J1:K27 貼上:
字母 轉碼
A 10
B 11
C 12
D 13
E 14
F 15
G 16
H 17
I 34
J 18
K 19
L 20
M 21
N 22
O 35
P 23
Q 24
R 25
S 26
T 27
U 28
V 29
W 32
X 30
Y 31
Z 33這份轉碼不能直接把字母順序加 9:例如 I 是 34、O 是 35、W 是 32、Z 是 33。使用明確對照表,之後也方便人工核對。
在 D2 輸入:
只有格式通過才查字母代碼
=IF(
C2,
XLOOKUP(LEFT(B2, 1), $J$2:$J$27, $K$2:$K$27),
""
)本篇參考健保署公開文件「身分證統一編號檢核原則」,PDF 第 38–39 頁的轉碼與權數;該文件標示版更日期為 112.08.25。本篇不是身分查詢服務。官方規則文件
第四步:算出不含檢查碼的加權和
在 E2 輸入:
字母拆兩位,再加上第 2 到第 9 碼的加權值
=IF(
C2,
INT(D2/10) + MOD(D2, 10)*9 +
SUMPRODUCT(
ARRAYFORMULA(VALUE(MID(B2, SEQUENCE(8, 1, 2), 1))),
{8;7;6;5;4;3;2;1}
),
""
)字母轉成兩位數後,十位乘 1、個位乘 9;接著將原編號第 2 到第 9 碼,依序乘 8、7、6、5、4、3、2、1。最後一碼先不參與這一步。
官方文件的示範會先取每個乘積的個位數再加總;本例保留完整乘積,最後才取模10。兩種總和可能不同,但相差的都是10的倍數,因此會得到相同尾碼。不要把中間加權和必須完全相同,誤當成校驗條件。
例如合成值 A100000001:A 轉成 10,前段貢獻 1;接著的 1 乘 8,其餘為 0,加權和就是 9。把這個中間結果獨立放一欄,比整段塞進一條長公式容易排錯。
第五步:把加權和補成 10 的倍數
在 F2 輸入:
餘數為 0 時,應有尾碼也必須是 0
=IF(
C2,
MOD(10-MOD(E2, 10), 10),
""
)加權和的個位數是 9,應有尾碼就是 1;加權和已是 10 的倍數,尾碼就是 0。外面再取一次 MOD(...,10),就是避免把「應該是 0」算成 10。
合成測例 A100000010 的加權和是 10,F 欄應得到 0。
第六步:輸出有意義的狀態
在 G2 輸入:
區分未填、格式不符與檢查碼不符
=IF(
B2="",
"未填",
IF(
NOT(C2),
"格式不符",
IF(
F2=VALUE(RIGHT(B2, 1)),
"格式與檢查碼通過",
"檢查碼不符"
)
)
)選取 B2:G2,往下填滿到 B18:G18。對照重點:
| 測例 | 預期 |
|---|---|
A100000001、A200000003 | 格式與檢查碼通過 |
A100000010 | 通過,應有尾碼為 0 |
| I、O、W、Z 開頭的四個合成例 | 通過,使用對照表的非順序代碼 |
A100000002 | 格式通過,檢查碼不符 |
| 小寫與前後半形空白測例 | 清理後通過 |
| 空白 | 未填 |
| 全形、中間空白、缺字母或其他證件樣式 | 格式不符 |
上表 17 筆合成資料的結果如上。這些狀態都只描述本例的本機規則。不要把「格式與檢查碼通過」改成「真實身分證」或「已驗證本人」。
自己練習與排錯
- 把
A2尾碼從 1 改成 2,確認只變成檢查碼不符;再還原為 1。 - 暫時把對照表中 I 的代碼改成按字母順序猜出的數字,觀察 I 測例是否失敗;完成後務必還原為 34。
- 檢查格式錯誤的列,
D:F應保持空白,不應產生誤導的數字。
這組公式以文字或一般數值輸入為前提,沒有替來源儲存格的錯誤值做全面處理。對照表被刪除、公式被覆蓋或範圍改動,都應先修正來源,不用 IFERROR 把所有問題包成通過。
想先練格式表達式,可看 REGEX 基礎;要把規則接到一般輸入流程,可參考資料驗證實戰。實際處理資料時,僅在有必要的欄位使用校驗,避免為了練習收集他人的完整證號。
本篇改寫自方格子的校驗公式拆解,以政府規則重新界定國民身分證格式,保留原始值與可核對的中間結果。
接下來可以
相關文章
查看所有文章正規表示式入門:REGEXMATCH、REGEXEXTRACT、REGEXREPLACE 與基本符號
從 T-17 這種編號開始,學會 REGEXMATCH 判斷、REGEXEXTRACT 擷取、REGEXREPLACE 取代,以及 . \d \w [] + * ? {n} ^ $ () | 這些基本符號,最後用「尋找並取代」套用規則運算式。
文字清理函式參考:TRIM、CLEAN、SUBSTITUTE、PROPER 與看不見的空格
整理 TRIM、CLEAN、SUBSTITUTE、REPLACE、UPPER、LOWER、PROPER 的語法與限制,包含 TRIM 清不掉全形空格與 CHAR(160)、CLEAN 只清 ASCII 0 到 31、SUBSTITUTE 第 4 參數只換第 N 次,以及用 UNICODE 找出看不見的字元。
資料驗證實戰:把訂單登記表的輸入錯誤擋在門口
以手搖飲門市的訂單登記表為例,設定下拉選單(含來自範圍與晶片樣式)、數字與日期範圍,再用 COUNTIF 擋重複的訂單編號、REGEXMATCH 擋格式不對的手機號碼,並說明拒絕輸入與顯示警告該怎麼選。
留言討論
共 0 則留言
