趁著演講者在講些五四三的時候,來補我的不務正業系列,這次來看看信用卡卡號驗證。
信用卡(圖片來源:信用卡的編碼規則,相較之下稍微稍微複雜點。根據 ISO/IEC 7812 標準,信用卡一般在 13~19 碼,但 Mastercard 旗下似乎有 12 碼簽帳金融卡(Debit Card)。而在臺灣比較常見的長度是 16 碼,因此下面在說明多以 16 碼來說明,但不管幾碼編碼規則其實都是相同的。
長達 16 碼的信用卡卡號,其實是由 3 部分所組成的,以一張卡號為 4311-4656-0640-6131
的 Visa 信用卡為例:
發卡機構代碼 | 個人帳戶號碼 | 檢核碼 | |||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
4 | 3 | 1 | 1 | 4 | 6 | 5 | 6 | 0 | 6 | 4 | 0 | 6 | 1 | 3 | 1 |
發卡機構代碼(Issuer Identification Numbers,IIN)
IIN 有時被稱為銀行識別號碼(Bank Identification Number,BIN),這是用來辨別卡片的主要資訊,由 行業標識碼(Major Industry Identifier,MII)為首所組成的 6 碼數字。
因此可以從左起第 1 碼數字能看出發卡組織的端倪。一般來說,5 開頭是萬事達卡、4 是 Visa為、3 是美國運通與 JCB、62 是中國銀聯。不過這些編碼似乎會因為商業聯盟與組織營運,如果要查確切的對應,可能得去查查美國國家標準協會(American National Standards Institute,ANSI) 的 IIN 資料庫。
帳戶號碼(Primary Account Number, PAN)
中間位數由發卡單位自定義,一般由 6~12 碼數字所組成。其意義並沒有硬性規定,可能會包含分行之類的訊息,但也有可能只是流水號。
檢核碼(Checking Number)
顧名思義就是用檢查這組信用卡的卡號真偽的一個數字,由 Luhn 演算法計算所得出。
在找資料的時候發現,有些文章的檢查規則是照著 Luhn 演算法的生成規則一步步計算的,但我想檢查不是生成,有些動作可以適度的化簡:
設定權重
由右到左為每個數字賦予一個權重,其中奇數位的權重是 1、偶數位的權重是 2:
Index | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
卡號 | 4 | 3 | 1 | 1 | 4 | 6 | 5 | 6 | 0 | 6 | 4 | 0 | 6 | 1 | 3 | 1 |
權重 | 2 | 1 | 2 | 1 | 2 | 1 | 2 | 1 | 2 | 1 | 2 | 1 | 2 | 1 | 2 | 1 |
乘積計算
將卡號每碼與其對應的權重一一相乘,若乘積大於 10 則取兩位數之和。
Index | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
乘積 | 8 | 3 | 2 | 1 | 8 | 6 | 10 | 6 | 0 | 6 | 8 | 0 | 12 | 1 | 6 | 1 |
取和 | 8 | 3 | 2 | 1 | 8 | 6 | 1 | 6 | 0 | 6 | 8 | 0 | 3 | 1 | 6 | 1 |
10的倍數
將取和完成的數值進行加總,若總和為 10 的倍數,則為有效卡號:
將上面的例子套回計算式後:
餘數為 0,表為有效卡號。
這組程式碼能加 log 的地方也只有長度檢查的部份,所以就不再寫一版有 log 的了。是說原本想寫 Clojure,不過 Clojure 還不是很熟練,邊寫還要邊查語法,有點太花時間了,改天再來補 Clojure 的程式碼好了。
本文作者: 辛西亞.Cynthia
本文連結: 辛西亞的技能樹 / hackmd 版本
版權聲明: 部落格中所有文章,均採用 姓名標示-非商業性-相同方式分享 4.0 國際 (CC BY-NC-SA 4.0) 許可協議。轉載請標明作者、連結與出處!