會員註冊、保險投保、實名制報名表單常常需要身分證字號。身分證字號的最後一碼是檢查碼,前端可以在送出前擋下打錯或亂填的號碼。本文整理官方公開的編碼規則與算法,提供一個在 Node.js 測試過的 TypeScript 函式,並說明 WebberUI 的 taiwan-id-input 元件怎麼處理驗證與遮罩。
文中出現的號碼都是示範用的假資料,只是剛好符合檢查碼規則,不對應任何真實個人。
號碼結構
依《國民身分證及戶口名簿格式內容製發相片影像檔建置管理辦法》第 3 條,統一編號共 10 碼:
- 第 1 碼:英文字母,代表直轄市、縣(市)別。
- 第 2 碼:性別碼,1 為男性、2 為女性。
- 第 3 至 9 碼:數字。
- 第 10 碼:檢查碼。
首字母轉碼表
計算前要先把首字母換成兩位數字。大部分字母從 A = 10 依字母順序往下編,但 I、O、W、X、Y、Z 的數值不照字母順序:
| 字母 | A | B | C | D | E | F | G | H | I | J | K | L | M |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 數值 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 34 | 18 | 19 | 20 | 21 |
| 字母 | N | O | P | Q | R | S | T | U | V | W | X | Y | Z |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 數值 | 22 | 35 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 32 | 30 | 31 | 33 |
常見的錯誤是照字母順序把 I 當成 18、把 O 當成 24,這樣一來,I、O、W、X、Y、Z 開頭的號碼都會算錯。
檢查碼算法
- 首字母換成兩位數,拆成十位與個位。例如 A = 10,拆成 1 和 0。
- 這兩位加上後面 9 碼數字,共 11 位。
- 11 位依序乘上權數
1, 9, 8, 7, 6, 5, 4, 3, 2, 1, 1,全部加總。 - 總和能被 10 整除即為有效。
以示範號碼 A123456789 為例:
| 位數 | A 十位 | A 個位 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 數字 | 1 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
| 權數 | 1 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 1 |
| 乘積 | 1 | 0 | 8 | 14 | 18 | 20 | 20 | 18 | 14 | 8 | 9 |
總和 130,能被 10 整除,所以檢查碼正確。
如果要從前 9 碼反推檢查碼,只算前 10 位(權數 1,9,8,7,6,5,4,3,2,1),檢查碼是 (10 - 總和 % 10) % 10。這和上面的判斷方式等價:最後一位權數是 1,加上檢查碼後總和剛好補到 10 的倍數。
新式外來人口統一證號
內政部移民署從 2021 年 1 月 2 日起核發新式外來人口統一證號。依移民署的〈新式統號的具體格式是什麼?〉說明:
- 格式改為 1 碼英文加 9 碼數字,和身分證字號相同。
- 第 1 碼是區域碼,依申請地區區分,比照國人格式。
- 第 2 碼是性別碼,8 為男性、9 為女性。
- 第 10 碼是檢查碼。
機關與業者流通的換發附件〈新式統一證號第 10 碼(檢查碼)計算邏輯〉使用同一張「國民身分證代號換算數字表」與同一組權數,範例號碼是 A800000014。我們用下方函式驗算,這組號碼通過檢查。
所以只要把第 2 碼的允許值從 1, 2 放寬到 1, 2, 8, 9,同一個函式就能處理國民與新式統號。外國籍會員佔一定比例的服務,一定要記得放寬,否則持新式統號的使用者會卡在註冊頁。
舊式統號是 2 碼英文加 8 碼數字,依移民署〈外來人口統一證號申請及換發送件須知〉,可以使用到 2030 年 12 月 31 日,2031 年 1 月 1 日起停用。如果你的服務在這段期間必須接受舊式統號,需要另外寫判斷,本文的函式不處理這種格式。
TypeScript 驗證函式
const LETTER_CODE: Record<string, number> = {
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,
};
const WEIGHTS = [1, 9, 8, 7, 6, 5, 4, 3, 2, 1, 1];
export function isValidTaiwanId(input: string): boolean {
const id = input.trim().toUpperCase();
// 第 2 碼:1、2 為國民身分證;8、9 為 2021 年起的新式外來人口統一證號
if (!/^[A-Z][1289]\d{8}$/.test(id)) return false;
const code = LETTER_CODE[id[0]];
const digits = [
Math.floor(code / 10),
code % 10,
...[...id.slice(1)].map(Number),
];
const sum = digits.reduce((acc, d, i) => acc + d * WEIGHTS[i], 0);
return sum % 10 === 0;
}在 Node.js 的測試結果:
| 輸入 | 結果 | 說明 |
|---|---|---|
A123456789 | 有效 | 常見的示範號碼 |
A800000014 | 有效 | 新式統號計算邏輯附件中的範例 |
a123456789 | 有效 | 函式會先轉成大寫 |
A123456788 | 無效 | 檢查碼不符 |
A323456789 | 無效 | 第 2 碼不是 1、2、8、9 |
AB12345678 | 無效 | 舊式統號格式,不在本函式範圍 |
另外隨機產生 20 萬組前 9 碼,每組配上 0 到 9 共 10 種檢查碼,確認每組恰好只有一個會通過,並且與 WebberUI 元件內建的 validateTaiwanId 結果一致。
個資處理
身分證字號屬於《個人資料保護法》所稱的個人資料,前端也要小心處理:
- 畫面上預設遮罩中段,只有使用者主動要求才顯示完整號碼。
- 不要把號碼放進 URL query、前端錯誤回報或分析事件。
- 檢查碼通過只代表格式正確,不代表號碼真的存在或屬於填寫的人。身分核實需要走正式的查驗管道。
用 WebberUI 的 taiwan-id-input 元件
taiwan-id-input 內建上面的檢核邏輯,輸入滿 10 碼即時驗證;預設遮罩中段四碼(顯示為 A12****789),可用眼睛按鈕切換;驗證通過時依首字母顯示縣市、依第 2 碼顯示性別小徽章。
把這個效果裝進你的專案
在專案資料夾執行指令,CLI 會加入原始碼與依賴套件,再依下方使用範例引用元件。
npx webberui@latest add taiwan-id-input用 WebberUI CLI 安裝:
npx webberui@latest add https://webberui.com/r/taiwan-id-input.json或在 components.json 設定 registries 後,改用 @webberui/taiwan-id-input 安裝。WebberUI 的元件可取得原始碼,安裝後檔案會放進你的 components/ui/,可以直接修改。
import { TaiwanIdInput, validateTaiwanId } from "@/components/ui/taiwan-id-input";
// 非受控:直接使用
<TaiwanIdInput onValidChange={(valid) => console.log(valid)} />
// 受控:自行管理值
const [id, setId] = React.useState("");
<TaiwanIdInput value={id} onChange={setId} masked />
// 也可單獨使用驗證函式
validateTaiwanId("A123456789"); // true(示範假資料)使用時要注意兩點:
- 元件輸入時會自動轉大寫,但單獨呼叫
validateTaiwanId時不會轉換,傳入小寫會回傳false。在後端或表單層重用時,先toUpperCase()。 - 元件接受第 2 碼為 1、2、8、9,也就是國民身分證與新式統號;舊式 2 碼英文的統號不會通過。
遮罩只作用在顯示層,onChange 與表單送出拿到的都是完整值。驗證結果透過 aria-live="polite" 區域朗讀,失敗時設定 aria-invalid;系統開啟「減少動態效果」時,停用搖晃與縮放動畫。
完整 props 見身分證字號輸入文件。表單如果也要填公司統編,可以參考統一編號驗證規則(2023 新制)與 React 輸入元件。