註:因為 UDN blog 新版會把除掉文章裡的單引號字元,我只能把程式碼中的註解全部改成 Rem 的寫法,尚請見諒。
身分證字號每個字元的意義
身分證字號的每個字元 (由左至右) 代表的意義如下:
(1)第一個字元為地區碼,代表最初登記戶籍的地區,如台北市為 A, 台中市為B,......
| A=10 台北市 | J=18 新竹縣 | S=26 高雄縣 |
| B=11 台中市 | K=19 苗栗縣 | T=27 屏東縣 |
| C=12 基隆市 | L=20 台中縣 | U=28 花蓮縣 |
| D=13 台南市 | M=21 南投縣 | V=29 台東縣 |
| E=14 高雄市 | N=22 彰化縣 | W=32 金門縣 |
| F=15 台北縣 | O=35 新竹市 | X=30 澎湖縣 |
| G=16 宜蘭縣 | P=23 雲林縣 | Y=31 陽明山 |
| H=17 桃園縣 | Q=24 嘉義縣 | Z=33 連江縣 |
| I=34 嘉義市 | R=25 台南縣 |
(2)第二個字元性別碼,代表此人的性別,1代表男性,2代表女性。
(3)第三個字元到第九個字元為流水號碼。
(4)第十個字元為檢查碼。
檢查碼產生的規則
1. 將地區碼轉換為相對代號,例如:A轉換成10兩個字元,B轉換成11……
對照如下:
| 字母 | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z |
| 代號 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 34 | 18 | 19 | 20 | 21 | 22 | 35 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 32 | 30 | 31 | 33 |
(需特別注意 I 、O 和 W 的代號)
2.將各數字乘上權數:
(1)英文字母轉成的數字, 個位數乘9再加上十位數
(2)第2~9個字元各數字從右到左依次乘以1、2、3、4......8
3.將乘上權數後之積相加 :
以 "A12345678?" 為例,以上的運算如下表:
|
字元 |
A |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | |
|
代碼值 |
1 |
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
|
權數 |
x1 |
x9 |
x8 |
x7 |
x6 |
x5 |
x4 |
x3 |
x2 |
x1 |
|
乘積 |
1 |
0 |
8 |
14 |
18 |
20 |
20 |
18 |
14 |
8 |
1 + 0 + 8 + 14 + 18 + 20 + 20 + 18 + 8 = 121
4.相加後之值除以10取其餘數 --
若餘數不為0:由 10 減去餘數得檢查號碼
若餘數為0:檢查碼為 0
以上面的例子來說,121 除以 10 得到餘數 1,所以檢查碼應為 9:
121 / 10 = 10 ......1
10 - 1 = 9
驗證身份字號的函數
底下這個 TestID 副程式裡面使用我設計的 CheckTwId() 函數來驗證 "A1234567890" 這一組身份證字號。
Sub test()
If Not CheckTwId("A123456780", ErrorMessage) Then
MsgBox ("身份證字號不正確:" & ErrorMessage)
End If
End Sub
因為正確檢查碼應該為 "9",所以執行後會顯示「身份證字號不正確:檢查碼檢核不正確」的訊息。
底下是CheckTwId() 函數的程式碼:
Public Function CheckTwId(ByRef strInput As String, ByRef ErrMsg) As Boolean
Dim strArea, strCID As String
Dim intArea, intCheckNum, intNumSum As Integer
Dim boolValidID As Boolean
boolValidID = True
If Len(strInput) <> 10 Then
Rem 字串長度必須為 10
ErrMsg = "長度不正確" & vbCrLf
boolValidID = False
Else
strFirst = Ucase(Mid(strInput, 1, 1))
Rem 取第一個字元為地區碼, 把小寫轉成大寫
intArea = InStr(1, "ABCDEFGHJKLMNPQRSTUVXYWZIO", strFirst, 1)
Rem 把字母轉換成 1~26 的數字,
If intArea = 0 Then
Rem 若第一個字元不是字母則 intArea 會是 0
ErrMsg = ErrMsg + "第 1 個字元非字母" & vbCrLf
boolValidID = False
End If
For i = 2 To 10
Rem 檢查第 2~10 個字元是否皆為數字
If InStr(1, "0123456789", Mid(strInput, i, 1), 1) = 0 Then
ErrMsg = ErrMsg + "第 " & i & " 個字元非數字" & vbCrLf
boolValidID = False
End If
Next i
Rem 檢查第 2 個字元是否為 1 或 2
If InStr(1, "12", Mid(strInput, 2, 1), 1) = 0 Then
ErrMsg = ErrMsg + "第 2 個字元非1或2" & vbCrLf
boolValidID = False
End If
End If
If boolValidID Then
intCheckNum = CInt(Right(strInput, 1))
Rem 取檢查碼來與計算結果比較
strCID = Format(intArea + 9) & Mid(strInput, 2, 8)
Rem 組成代碼值字串
intNumSum = 0
intNumSum = intNumSum + CInt(Mid(strCID, 1, 1))
Rem 左端第一碼乘以1(可免)
For i = 2 To 10
Rem 第2~10碼依序乘以 9~1 的權數並且加總起來
intNumSum = intNumSum + CInt(Mid(strCID, i, 1)) * (11 - i)
Next i
If (intNumSum Mod 10) = 0 Then
Rem 若除法計算出的餘數為 0 則碼檢核應為 0
If (intCheckNum <> 0) Then
boolValidID = False
ErrMsg = "檢查碼檢核不正確"
End If
Else
If (10 - (intNumSum Mod 10)) <> intCheckNum Then
ErrMsg = "檢查碼檢核不正確"
boolValidID = False
End If
End If
End If
CheckTwId = boolValidID
Rem 傳回表示結果的邏輯值
End Function
1樓. Guest2010/05/25 14:24A211000000 判斷為錯誤????
If (intNumSum Mod 10) = 0 Then '若除法計算出的餘數為 0 則
boolValidID = False
ErrMsg = "檢查碼檢核不正確"
??????????謝謝您的指正!很抱歉,我今天才發現您的留言。該處程式確實有誤,可能是編輯文章的時候誤刪了 (包括該處的註解也有一半不見了),剛才已經更正,再次致謝! Way Cheng 謹致 (2018/12/24) ThisIsTheWay 於 2018/12/24 19:31回覆






