小弟初心者程序員,技術還不高,
所以現在在解公司產品程式撰寫都會寫一些筆記or追code
這題挺有趣,放上來給大家討論一下,也希望我周一能夠解決XD
順帶一提,我寫的是coldfusion,這個應該很冷門,不過邏輯與html類似,不用太在意
概述
「網路辦證」證號判讀原則,政府現行「居留證號」及「戶號」編碼原則已有相關修訂,導致以新原則編號的讀者,輸入號碼時顯示「無效證號」,請協助調整設定及頁面顯示。謝謝!
「居留證號」原先「2碼英文+8碼數字」,可再接受如同身分證號「1碼英文+9碼數字」。
「戶號」可接受「1碼英文+7碼數字」或「2碼英文+6碼數字」。
※政府現行相關編碼原則,參見下列,
居留證號:https://www.immigration.gov.tw/5382/5385/5388/7178/225074/
戶號:https://www.moi.gov.tw/chi/chi_faq/faq_detail.aspx?t=2&n=14944&p=7&f=2
基本上這題就是身分證除了台灣人民使用,可能還有一些別的身份的人也會有身份證,他也應該可以用這組字號去借書等等的事情,但系統會將其攔截。
現在身份證攔截規則只有符合舊有規則的一般身分證字號才不會被攔截,所以說要加入考量新的條件的身份證規則即可辦證
好的,那先搞懂一般台灣身份證的判別式大概長怎樣?
看看我們怎麼寫的
https://hackmd.io/@CynthiaChuang/CheckUID#
這邊真的講得很好,我一開始真的不知道為什麼要這樣寫
若改寫成數學判斷式:
(n0×1+n1×9+n2×8+n3×7+n4×6+n5×5+n6×4+n7×3+n8×2+n9×1+n10×1)%10=0
身份證為A123456789為例
算式就會是
(1×1+0×9+1×8+2×7+3×6+4×5+5×4+6×3+7×2+8×1+9×1)%10
=(1+0+8+14+18+20+20+18+14+8+9)=130%10=0
為有效證號
以我為例H124968043
算式就會是
(1×1+7×9+1×8+2×7+4×6+9×5+6×4+8×3+0×2+2×1+5×1)%10=
(1+63+8+14+24+45+24+24+0+4+3)%10
=210%10
=0
餘數為零,為有效證號
所以說整個身分證字號只判斷了前面三碼
A~Z(地區) 男女(1,2) 區域(一般台灣人通常為0~5)
區域碼 A-Z
性別碼男:1 女:2
身分碼 其他:0-5,取得國籍之外國人:6,無戶籍國民:7,港澳居民:8,大陸地區人民:9
流水碼 阿拉伯數字
檢核碼 阿拉伯數字
以我為例H124968043透過上述算式算出為合法的有效身分證
如果我改成Z124968043可就不行了
OKOK
其實身分證這題不用改,要改的是居留證號與家庭借閱戶號
有關居留證號的部分
一、 前言:
舊式外來人口統一證號(2碼英文+8碼數字,以下簡稱舊式統號)
因與國民身分證字號(1碼英文+9碼數字)格式不同,使外來人口無法順暢進行網購、訂票、醫療掛號等各項事務,歐洲在臺商務協會亦多次藉由每年公布之白皮書,向政府單位提出前揭問題。
二、 推動情形:
(一) 為建立友善外來人口環境,本署參考歐洲在臺商務協會建議,將舊式統號比照國民身分證字號編碼原則,改版為新式外來人口統一證號(1碼英文+9碼數字,以下簡稱新式統號),格式說明如下:
不會顯示無效證號,此為舊式有效證號
這樣就會出錯了,因為舊的系統判定第二位一定要為英文
二、 推動情形:
(一) 為建立友善外來人口環境,本署參考歐洲在臺商務協會建議,將舊式統號比照國民身分證字號編碼原則,改版為新式外來人口統一證號(1碼英文+9碼數字,以下簡稱新式統號),格式說明如下:
其實跟身分證一樣,唯一差別在性別碼原本為1,2改成8,9
而第3-9碼為流水號
然後第10碼一樣為檢查碼,為最後餘數為多少再加成餘數為0
嗯…有點複雜,不過他有提供新式的合法證號,我用身分證的公式去測測看會不會過
很神奇的..都會過(其實應該不神奇)
那我就直接把身分證的判別式拿來用啦!
不過有一點問題來了
我必須保留第二個英文字母一樣可以輸入而不會出錯
以身分證為例,因為我寫了如果第二字不為數字,就會判別無效
所以說
我要把居留證號做兩個判斷
第一個是前兩位英文的話,後面8碼隨便他,都會過
第二個是只有一位英文的話,必須遵照身分證格式
所以也意味著,我直接拿身分證的格式來套居留證攔截條件
會發生我打舊式身分證會出錯
(兩個英文的版本,因為不符合身分證條件)
So, if (\a-z\test.substr(0,1)){身分證格式}
Else if (\a-z\test.substr(0,2)) {舊式居留證freestyle格式}
於是我去找了那個部分的地方
我把!isNaN(card.substr(1,1))||這行註解,因為不要讓他一定需要這條件
這樣可以了,但是沒有加入身分證的判斷…
導致如果我使用新條件A123456783也會過(沒有經過有效證號判別)
我想這應該是最難的部分
因為你要讓他可以前面輸入兩個英文字的時候完全不阻擋
所以現在問題來了
如果說使用者有個input值為身分證字號
可能為 AA23456789 = 有效, A123456789 (有條件下的有效)
前者沒有為居留證就有規則,無須審核條件
而這個後者是有經過檢查碼審核過的
這樣的話該怎麼判斷不會互相衝突呢?(ifelse寫的好亂Orz)
如果透過Boolean的話是不是可以比較好寫呢?
請求大神指路~
都用 RE 了,就用 RE 檢查格式合法性
if($('#selectCard option:selected').val() == 2){ //居留證號
if(/[A-Z]{1}[8-9]{1}[0-9]{8}/.test(card)){ //身分證字號型式
//檢查邏輯
} else if (/[A-Z]{2}[0-9]{8}/.test(card)){ //雙字母居留證號型式
//檢查邏輯
}
}
這樣的話該怎麼判斷不會互相衝突呢?(ifelse寫的好亂Orz)
若是我,會獨立寫成數個函數,身份證函數、舊居留證函數、新居留證函數,各自獨立運作。
if (第1碼=A-Z AND 第2碼 = 1-2 ) 身份證函數()
if (第1碼=A-Z AND 第2碼 = A-Z ) 舊居留證函數()
if (第1碼=A-Z AND 第2碼 = 8-9 ) 新居留證函數()
寫成一個函數要判斷3種情形,程式看起來漂亮,但不好維護;萬一那一天,政府開放外星人可以取得我國身份證明,那您不就又要再翻修一次,再加新的判斷,程式更亂了。
橋歸橋,路歸路,各走各的通道,也保留未來新增通道之便利。
因為我有寫所得稅扣繳申報系統,這個問題,我就是這樣處理的,但事實上,判斷式不止三個,因為這個編碼規則,是經過很多次修正,以前還要分183天內和183外,編法不同,「外國」人和「鄰國」人的編法也不同,那些拿到舊證照的,也未必都更換新照完畢,會產生各式證照並存的現象,如果您不拆開的話,根本會糊成一鍋粥。
https://www.fia.gov.tw/download/676a5f3007d143d29a47ab2c28067ff6
P16~P17,有詳盡說明。
如果是我,
不會考慮用javaScript作,
不管你怎麼作,
我都可以破解.
建議是作在後端.
感謝ckp6250提供的文件:綜合所得稅資料電子申報作業要點
我寫某個戶政專案系統, 我使用單一涵式來處理三種證號: 台灣身分證證號, 舊版居留證證號, 和新版居留證證號. 這三種證號的檢查邏輯是一樣的, 關鍵在第二位的轉換:
1.台灣身分證證號: 1男性, 2女性
2.舊版居留證證號: A->0男性, B->1女性, C->2男性, D->3女性 (第2位英文字母的對應數值的個位數)
3.新版居留證證號: 8->1男性, 9->2女性 (數字減7)
我使用單一輸入欄位, 不讓使用者選擇證件種類, 除了輸入簡化外, 又可避免新手使用者混淆, 系統依第二位自動判斷三種身份, 檢核並回饋證件相關訊息, 如果使用者輸入的不是這三種證號, 那就歸類為錯誤.當然如果也可讓系統容許其他證號, 例如183天內無統號者, 輸入什麼就是什麼, 並無檢核邏輯可以檢核, 這種情形可用另一個欄位來管控這種證號. 如果有外星人, 以政府治理原則, 沒有必要創造新的檢核邏輯, 外星人一樣可以採用居留證編碼, 第二位還可以用3,4,5,6,7,0, 或者英文字母E~Z, 只要轉換成數字, 使用同一個檢核邏輯即可.
是否要拆成多個涵式來處理不同證件? 我的邏輯是不需要, 主要是因為系統自動判斷身份類別且檢核邏輯是一樣的, 而不是使用者輸入身份類別, 至於會不會混淆? 不會. 反而程式碼更簡潔清晰, 又可以達到低耦合封裝的要求. 我的程式碼是用VB寫的, 關於Javascript, 很合適, 我有考慮用Javascript寫成一個元件, 例如<taiwanid>
, 可以用在其他系統中.
依合約不能提供程式碼, 但透過證號第二位的轉換是關鍵的邏輯, 提供您參考.