iT邦幫忙

2022 iThome 鐵人賽

DAY 21
0
Modern Web

自己工具,自己 React - React學習系列 第 21

【D21】 小工具:身分證製造機(part 3)-檢查驗證碼

  • 分享至 

  • xImage
  •  

大部分檢查功能已經在昨日做完,剩下的就是最重要的檢查碼,現在來討論一下檢查碼如何做吧!(其實已經逃避兩天了 XD)

檢查碼規則

何謂檢查碼

Checksum 被稱為核對和(維基百科和國家教育研究院稱為「核對和」),是經過計算後產生的數值,用來檢核前面的值是否正確。像是我們會用 MD5 去把資料加密後,檢查是否正確,或有沒有被串改。而其中一種方法為「校驗碼」(Check digit)。

校驗碼通常為一組字的最後一碼,用來確認前面的資料都是正確的(應該說符合計算規則)。因為前面的值是經過某種計算後,才會產生校驗碼,因此可以用校驗碼快速的審核資料的正確性。身分證的尾碼就是屬於校驗碼,ISBN 最後一碼也是如此。

身分證檢查碼(校驗碼)規則

  • 首碼轉換

校驗碼太過文鄒鄒,因此用檢查碼作為代表。身分證的格式為:_英文_數數數數數數數數數,總共十碼(例如:A999999999)。這時需要把英文轉換成數值,然後再套入數學公式計算就可以算出檢查碼。

因此可以參考 Day19 的資料,找到每個代碼對應的數值為何:

代碼 數值 縣市
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 陽明山管理局

這邊使用維基百科的範例,使用合法(合乎計算規則)的身分證字號「A123456789」當作範例。

  • 個別乘上數值並加總

這時需要對照上表,把首碼的英文字變成兩個數,所以 A 轉化成 10,再加上後面九碼,就成為一組 11 碼的數值。

A 1 2 3 4 5 6 7 8 9
1 0 1 2 3 4 5 6 7 8 9

接著再把這個數值,依序乘上 19876543211,然後再相加:

1*1 + 0*9 + 1*8 + 2*7 + 3*6 + 4*5 + 5*4 + 6*3 + 7*2 + 8*1 + 9*1 = 130

這組數字的總和為 130

如果把它加上表,會更清楚:

證號 A 1 2 3 4 5 6 7 8 9
數值 1 0 1 2 3 4 5 6 7 8 9
乘數 1 9 8 7 6 5 4 3 2 1 1
  • 總合可以被 10 整除就是正確的編號

取得加總後的值後,除以 10 取得餘數,當餘數為 0 時(也就是餘除 10 是為 0),表示這組身分證字號為合規的。

130 % 10 = 0

製作檢查碼

檢查碼的功能命名為 checkCkDigit() ,裡面包含轉換英文、數字加總、是否整除等三大部分。

function checkCkDigit(code) {
  const placeCode = checkPlace(code.substring(0, 1)); // 取得首碼的數值
  const bodyCode = code.substring(1, 9); //取得中間非驗證碼的數值
  const lastCode = code.substring(8); //取得尾碼
  const idSum = calHead(placeCode) + calBody(bodyCode) + parseInt(lastCode) * 1; //計算總和 //尾數的*1 其實可以不用乘
  const modResult = idSum % 10;
  const result = modResult === 0;

  console.log(
    `sum = ${idSum}, mod result = ${modResult}, check result = ${result}`
  );
  return result;
}

function calBody(code) {
  let sum = 0;
  for (let i = 0; i < code.length; i++) {
    sum += parseInt(code[i]) * (8 - i);
  }
  console.log(`body sum = ${sum}`);

  return sum;
}

function calHead(code) {
  let sum = parseInt(code[0]) * 1 + parseInt(code[1]) * 9;
  console.log(`head sum = ${sum}`);

  return sum;
}

其中需要增加 calHeadcalBody,用來計算首碼,和後面八碼數字,由於最後的驗證碼是一位數,並且直接乘與 1,因此就直接放在算式中。

最後再把總合,進行模除(mode,%),如果整除就是合規的格式。


後記

總算完成了,檢查碼比我想像的還要花時間,雖然完成,但是還有很多要優化,就繼續加油吧~


上一篇
【D20】 小工具:身分證製造機(part 2)-身分證檢查功能
下一篇
【D22】 小工具:身分證製造機(part 4)-製作檢查頁面
系列文
自己工具,自己 React - React學習30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言