iT邦幫忙

1

JavaScript同時判別不同條件下有效身分證字號

  • 分享至 

  • xImage

小弟初心者程序員,技術還不高,
所以現在在解公司產品程式撰寫都會寫一些筆記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://ithelp.ithome.com.tw/upload/images/20210904/20137810JT5KYcZF5I.jpg

https://hackmd.io/@CynthiaChuang/CheckUID#
這邊真的講得很好,我一開始真的不知道為什麼要這樣寫

https://ithelp.ithome.com.tw/upload/images/20210904/20137810WHGjmjdM5L.jpg

若改寫成數學判斷式:
(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. 第1碼:區域碼,依申請地區分,比照國人格式。
  2. 第2碼:性別碼,8為男性,9為女性。
  3. 第10碼:檢查碼。

https://ithelp.ithome.com.tw/upload/images/20210904/20137810QCfDDkYvLd.jpg
不會顯示無效證號,此為舊式有效證號
https://ithelp.ithome.com.tw/upload/images/20210904/20137810ua9o16OeTy.jpg
這樣就會出錯了,因為舊的系統判定第二位一定要為英文

二、 推動情形:
(一) 為建立友善外來人口環境,本署參考歐洲在臺商務協會建議,將舊式統號比照國民身分證字號編碼原則,改版為新式外來人口統一證號(1碼英文+9碼數字,以下簡稱新式統號),格式說明如下:

  1. 第1碼:區域碼,依申請地區分,比照國人格式。
  2. 第2碼:性別碼,8為男性,9為女性。
  3. 第10碼:檢查碼。

其實跟身分證一樣,唯一差別在性別碼原本為1,2改成8,9
而第3-9碼為流水號
然後第10碼一樣為檢查碼,為最後餘數為多少再加成餘數為0
嗯…有點複雜,不過他有提供新式的合法證號,我用身分證的公式去測測看會不會過
https://ithelp.ithome.com.tw/upload/images/20210904/201378105BPZvV8ZxJ.jpg
很神奇的..都會過(其實應該不神奇)
那我就直接把身分證的判別式拿來用啦!

不過有一點問題來了
我必須保留第二個英文字母一樣可以輸入而不會出錯
以身分證為例,因為我寫了如果第二字不為數字,就會判別無效
https://ithelp.ithome.com.tw/upload/images/20210904/20137810egloOVx0VQ.jpg

所以說
我要把居留證號做兩個判斷
第一個是前兩位英文的話,後面8碼隨便他,都會過
第二個是只有一位英文的話,必須遵照身分證格式
所以也意味著,我直接拿身分證的格式來套居留證攔截條件
會發生我打舊式身分證會出錯
(兩個英文的版本,因為不符合身分證條件)
So, if (\a-z\test.substr(0,1)){身分證格式}
Else if (\a-z\test.substr(0,2)) {舊式居留證freestyle格式}

於是我去找了那個部分的地方
https://ithelp.ithome.com.tw/upload/images/20210904/201378105Cygem354n.jpg
我把!isNaN(card.substr(1,1))||這行註解,因為不要讓他一定需要這條件
https://ithelp.ithome.com.tw/upload/images/20210904/20137810lq9KYrxcPt.jpg
這樣可以了,但是沒有加入身分證的判斷…
導致如果我使用新條件A123456783也會過(沒有經過有效證號判別)
我想這應該是最難的部分
因為你要讓他可以前面輸入兩個英文字的時候完全不阻擋

所以現在問題來了
如果說使用者有個input值為身分證字號

可能為 AA23456789 = 有效, A123456789 (有條件下的有效)
前者沒有為居留證就有規則,無須審核條件
而這個後者是有經過檢查碼審核過的
這樣的話該怎麼判斷不會互相衝突呢?(ifelse寫的好亂Orz)
如果透過Boolean的話是不是可以比較好寫呢?
請求大神指路~

看更多先前的討論...收起先前的討論...
ckp6250 iT邦好手 1 級 ‧ 2021-09-04 13:49:58 檢舉
A123456789 ,不會有效,
我底下附的連結,有明文規定。
bill0704 iT邦新手 5 級 ‧ 2021-09-05 09:03:14 檢舉
男人的堅持嗎...其實我看不太懂你寫的
但如果你的意思是新式外國證可以用本國身份證的公式完成,要怎麼改才可以兼容的話:
1.把身份證判別封裝成function
2.不要改動舊版雙英文字母外國證的code
3.加elif判斷

這樣code應該會蠻乾淨的
感謝各位前輩,我已經判斷出來了
我沒有多寫很多函式,一樣寫在同一個並且用RE判斷,要多一個判斷就多出一趟if else
目前應該是可以正常判斷,不過最一開始只能寫[A-Z]{2}就好
如果再往下寫re判斷會讓系統有一段空窗期無法判定

小弟的方法也許不是最好的,也可能會有其他BUG,不過目前已經可以完成,感謝
bizpro iT邦大師 1 級 ‧ 2021-11-16 14:08:03 檢舉
提供參考:
1. 舊式居留證號有審核規則, 第二碼只有A,B,C,D, 分別轉成0,1,2,3, 其中0,2為男性, 1,3為女性, 之後就跟一般身分證號一樣進行檢核:
A-->10-->0, B-->11-->1,C-->12-->2,D-->13--3
出現其它英文字母則為錯誤.

2. 關於第三碼身分碼,:
0~5以第一碼分(1)國人, 或(2)歸化移民和無國籍者.
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中
1
海綿寶寶
iT邦大神 1 級 ‧ 2021-09-04 07:46:35
最佳解答

都用 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)){  //雙字母居留證號型式
       //檢查邏輯
    }
}

哇!這個感覺可以!

ckp6250 iT邦好手 1 級 ‧ 2021-09-04 13:48:00 檢舉

形式要件的判斷式,沒這麼單純哦,
作業要點上有寫,很多項的。

2
ckp6250
iT邦好手 1 級 ‧ 2021-09-04 05:27:23

這樣的話該怎麼判斷不會互相衝突呢?(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,有詳盡說明。

看更多先前的回應...收起先前的回應...

嗯…確實會糊成一鍋粥
我原本想直接把判定身分證的條件塞到居留證下
結果感覺這樣幹不妥?

ckp6250 iT邦好手 1 級 ‧ 2021-09-04 13:51:50 檢舉

我的建議,按照我附的連結,
把P16~P17看一遍,
照著做程式,不然,一定會遇到被您誤殺或誤放的情形。

我看完他落落長的敘述
第一直覺也是為啥不拆開?
在堅持什麼 = =

bill0704 iT邦新手 5 級 ‧ 2021-09-05 09:16:36 檢舉

如果外星人能來地球的話...他們大多技術與知識會比我們先進。除非愛台灣,不然不需要特地過來借書啦

1
小魚
iT邦大師 1 級 ‧ 2021-09-04 10:04:29

如果是我,
不會考慮用javaScript作,
不管你怎麼作,
我都可以破解.
建議是作在後端.

ckp6250 iT邦好手 1 級 ‧ 2021-09-04 13:42:01 檢舉

同意,
如果是我,
會直接寫在資料庫的 stored procedure 裡。

0
bizpro
iT邦大師 1 級 ‧ 2021-09-06 13:38:25

感謝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>, 可以用在其他系統中.

依合約不能提供程式碼, 但透過證號第二位的轉換是關鍵的邏輯, 提供您參考.

我要發表回答

立即登入回答