雜記 › 技術筆記 › 身分證最後一位為什麼是 X?前 17 位加權取模算出的校驗碼

身分證最後一位為什麼是 X?前 17 位加權取模算出的校驗碼

表單提示身分證號無效、自己卻確定沒填錯;或者寫校驗時想知道到底該信哪一層。這兩種情況都要回到那一位校驗碼:它是前 17 位算出來的,末尾那個 X 也只是同一個演算法的結果。整條鏈路只有三步——加權、求和、取餘查表。

18 位號碼的結構

前 6 位是地址碼,接著 8 位是出生日期,再 3 位順序碼(同一天同一區域內的排列,末位奇偶區分性別),最後 1 位是校驗碼。前 17 位攜帶全部身分資訊,第 18 位什麼都不攜帶,它只負責一件事:讓前面 17 位可以被算術驗證。

三步算出校驗位

  1. 前 17 位逐位乘以權重 7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2,再把 17 個乘積相加。
  2. 用這個和對 11 取餘,餘數落在 0 到 10 之間。
  3. 按餘數查表得到校驗位:0 到 10 依次對應 1,0,X,9,8,7,6,5,4,3,2。

拿一個公開的示範號段走一遍:前 17 位 11010519491231002,加權求和得 167,167 除以 11 餘 2,查表得到 X,完整號碼就是 11010519491231002X。

位序數字權重乘積
1177
2199
30100
4155
5080
65420
7122
8919
94624
109327
11177
122918
1331030
14155
15080
16040
17224

右列 17 個乘積相加:7+9+0+5+0+20+2+9+24+27+7+18+30+5+0+0+4 = 167。這張表也是最好用的核對載體——自己算一遍如果對不上 167,就是某一位的權重抄錯了。

權重不是隨手定的

那串 7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2 是 2 的次方取模的產物:第 i 位(從 1 數起)的權重等於 2 的 (18−i) 次方對 11 取餘。逐位推一遍能全部對上——2 的 17 次方模 11 得 7,2 的 16 次方得 9,2 的 15 次方得 10,一路降到 2 的 1 次方得 2。查表那一步同樣有出處:餘數 r 對應的校驗值就是 (12 − r) 對 11 取餘,r 為 2 時算出 10,而 10 只能寫成 X。

X 不是留給誰的特殊標記

按公式,餘數為 2 的這一檔算出來的校驗值是 10。號碼要求每一位都是單一字元,而 10 是兩位,就用羅馬數字 X 頂替佔這一格。所以末位是 X 只說明前 17 位的加權和恰好模 11 餘 2,與出生日期、登記地區都沒有關係,更不是什麼特殊身分的標識。

它能發現什麼、發現不了什麼

2 的任何次方對 11 取餘都落在 1 到 10 之間,永遠不為 0——餘數序列是 2,4,8,5,10,9,7,3,6,1,然後回到 2,週期為 10。把某一位從 d 改成 e,加權和的變化量是 (e−d) 乘以該位權重;要讓改動察覺不到,這個乘積就得是 11 的倍數,而 |e−d| 最大只有 9,權重本身又不是 11 的倍數,湊不出來。我把 17 個位置上所有可能的單字元改動枚舉了一遍:每個位置有 9 種別的數字可填,共 153 種,改完之後校驗位仍等於原值 X 的有 0 種。所以「一次手滑逃掉」不是機率小,是不可能。

它管不到的是換位。權重表以 10 為週期,第 1 位與第 11 位同為 7、第 2 位與第 12 位同為 9,這樣一路到第 7 位與第 17 位同為 2,共七對。數字落在這七對位置裡互相調換時,加權和完全不變,校驗位照樣對得上。這是所有單校驗位方案共同的上限,不是實作寫錯了。

它還保證不了算術之外的任何事:隨機拼一串 18 位數字,校驗位恰好碰對的機率是十一分之一。固定隨機種子跑 200000 組隨機前 17 位,末位等於 X 的有 18063 組,佔 9.03%,與理論值 9.09% 差 0.06 個百分點。也就是說它擋手滑很有效,擋編造幾乎沒有作用,更不能證明這個號碼對應一個真實存在的人。

15 位舊號碼怎麼變成 18 位

出生年月日從 6 位(YYMMDD)擴到 8 位(YYYYMMDD)時,年份前補上世紀碼,末尾再加一位校驗。示範號去掉世紀寫法是 110105491231002,把 49 補成 1949 之後前 17 位就是 11010519491231002,按三步算出 X,完整的 18 位得到 11010519491231002X。反向做也成立:刪掉校驗位、再把年份的世紀碼去掉,就還原成 15 位寫法。處理歷史資料時這一段最容易被漏,因為 15 位號碼根本沒有校驗位可查。

工程上分幾層來做

輸入框裡的即時校驗跑到校驗位這一層就夠,它攔得住打錯的;需要更硬的確認,就得走實名核驗那類通道,兩層的成本和能給出的結論完全不同。展示的時候它屬於敏感欄位,列表裡要能辨認又不能整串露出,隱私資訊遮蔽 處理的就是這類需求。想看同一個思路在別的號碼上怎麼落地,銀行卡校驗工具 用的是另一套加權取模規則,權重不同但結構一致;要逐位核對本站這串權重,身分證號碼校驗 會把加權和、餘數與查表結果一併列出來。

Q:改一位能發現,改兩位為什麼就不一定

單字元改動會改變加權和,而權重的選取讓這種改動很難落回同一個餘數。同時改兩位時,如果兩處帶來的差值互相抵消,和沒變、餘數沒變,校驗位就對得上了。這是所有單校驗位方案共同的上限,不是實作寫錯了。

Q:地址碼和出生日期它不管嗎

校驗位只看整串 17 位的加權和,不判斷 6 位區劃碼是否真實存在,也不判斷日期是否合法、是否為閏年。完整的格式校驗通常還要補一層出生日期範圍檢查,那是另外一段獨立的邏輯。

Q:X 大寫小寫都行嗎

規則裡是 X。多數系統會在輸入時容忍小寫再轉大寫,但儲存和比對最好統一成一種寫法,否則同一個號碼會因為大小寫差異被判成兩筆不同記錄。

📎 相關文章

PNG 壓了三遍只減 426 位元組:無損壓縮的真實邊界 2026-10-22 WebP 轉 PNG 後體積漲了幾倍:什麼時候必須轉,怎麼把漲幅壓住 2026-10-22 截圖縮到四分之一,小字糊成一團的三種原因 2026-10-22 同樣裁 300×300,頭像為什麼總偏右下角半格 2026-10-22 按每月 1.7 倍預估 18 個月,腳本和表格為什麼給出兩個數 2026-10-22