Skip to content

Instantly share code, notes, and snippets.

@5SMNOONMS5
Last active February 13, 2023 02:42
Show Gist options
  • Save 5SMNOONMS5/66b3edcf2a00197a65347747bdd2d626 to your computer and use it in GitHub Desktop.
Save 5SMNOONMS5/66b3edcf2a00197a65347747bdd2d626 to your computer and use it in GitHub Desktop.
台灣身分證認證 swift 5
//A 台北市 J 新竹縣
//B 台中市 K 苗栗縣 T 屏東縣
//C 基隆市 U 花蓮縣
//D 台南市 M 南投縣 V 台東縣
//E 高雄市 N 彰化縣 W 金門縣
//F 台北縣 O 新竹市 X 澎湖縣
//G 宜蘭縣 P 雲林縣
//H 桃園縣 Q 嘉義縣 Z 連江縣
//I 嘉義市
// 2010年12月25日 更新不再賦配代碼的區域
// L 台中縣 R 台南縣 S 高雄縣 Y 陽明山
func checkID(source: String, bornAfter20101225: Bool = false) -> Bool {
/// 轉成小寫字母
let lowercaseSource = source.lowercased()
/// 檢查格式,是否符合 開頭是英文字母+後面9個數字
func validateFormat(str: String) -> Bool {
let regex: String = "^[a-z]{1}[1-2]{1}[0-9]{8}$"
let predicate: NSPredicate = NSPredicate(format: "SELF MATCHES[c] %@", regex)
return predicate.evaluate(with: str)
}
if validateFormat(str: lowercaseSource) {
/// 判斷是不是真的,規則在這邊(https://zh.wikipedia.org/wiki/中華民國國民身分證#驗證規則)
var cityAlphabets: [String: Int] = [
"a":10, "b":11, "c":12, "d":13, "e":14,
// 臺北市 臺中市 基隆市 臺南市 高雄市
"f":15, "g":16, "h":17, "i":34, "j":18,
// 新北市 宜蘭縣 桃園市 嘉義市 新竹縣
"k":19, "m":21, "n":22, "o":35, "p":23,
// 苗栗縣 南投縣 彰化縣 新竹市 雲林縣
"q":24, "t":27, "u":28, "v":29, "w":32,
// 嘉義縣 屏東縣 花蓮縣 臺東縣 金門縣
"x":30, "z":33
// 澎湖縣 連江縣
]
// 2010年12月25日 更新不再賦配代碼的區域,但是 2010 年前還是需要判斷。
if !bornAfter20101225 {
let notSupportCities = [
"l":20, "r":25, "s":26, "y":31
// 台中縣 台南縣 高雄縣 陽明山管理區
]
cityAlphabets.merge(notSupportCities) { current, _ in current }
}
/// 把 [Character] 轉換成 [Int] 型態
let ints = lowercaseSource.compactMap{ Int(String($0)) }
/// 拿取身分證第一位英文字母所對應當前城市的
guard let key = lowercaseSource.first,
let cityNumber = cityAlphabets[String(key)] else {
return false
}
/// 經過公式計算出來的總和
let firstNumberConvert = (cityNumber / 10) + ((cityNumber % 10) * 9)
let section1 = (ints[0] * 8) + (ints[1] * 7) + (ints[2] * 6)
let section2 = (ints[3] * 5) + (ints[4] * 4) + (ints[5] * 3)
let section3 = (ints[6] * 2) + (ints[7] * 1) + (ints[8] * 1)
let total = firstNumberConvert + section1 + section2 + section3
/// 總和如果除以10是正確的那就是真的
if total % 10 == 0 { return true }
}
return false
}
let id = "LXXXXXXXXX"
let shouldFalse = checkID(source: id, bornAfter20101225: true)
let shouldTrue = checkID(source: id, bornAfter20101225: false)
@bob910078
Copy link

Hi @5SMNOONMS5

地區代號對應的數字好像有錯,我是看這邊的規則:
https://zh.wikipedia.org/wiki/中華民國國民身分證#驗證規則

需要修改的部分是 cityAlphabets 這個變數宣告:

var cityAlphabets: [String: Int] = [
	"a":10,"b":11,"c":12,"d":13,"e":14,"f":15,"g":16,"h":17,"i":34,"j":18,"k":19,
	"m":21,"n":22,"o":35,"p":23,"q":24,"t":27,"u":28,"v":29,"w":32,"x":30,"z":33,
	"l":20,"r":25,"s":26,"y":31,            // 已停用代碼
]

@5SMNOONMS5
Copy link
Author

@bob910078 感謝回覆,我有加上一個判斷,驗證是否在 2010 - 12 - 25 前後出生的

@konekoya
Copy link

Thanks for sharing this :)

@5SMNOONMS5
Copy link
Author

5SMNOONMS5 commented Oct 7, 2021

Thanks for sharing this :)

haha ur welcome

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment