日本政府近年来在大力度地推行 My Number Card(マイナンバー 個人番号)的制度,想使用这套系统来代替个人情报的验证,在日本居住的所有人都可以向日本政府申请一个个人番号,这个番号每一个人终身都只有一个,就类似于国内的身份证号,或者没过的 SSN 社会保险号一样,会跟随着一个人一生。更甚至最近有看到新闻说,日本的药局和医院正在推行 My Number 卡在购药时,可以查看当前买药的人的用药历史,来避免可能产生的药物问题。
My Number 的号码规则
日本的 My Number 是一个 12 位的数字
Java 实现
public class Main {public static void main(String[] args) {System.out.println(validateMyNumber("123456789012"));
}
public static boolean validateMyNumber(String myNumber) {
// 整数列化
int[] digits = myNumber.chars().map(Character::getNumericValue).toArray();
// 12 桁しか認めない
if (digits.length != 12)
return false;
// チェックデジットを分離します
int checkDigit = digits[digits.length-1];
// 残った数字を小さい方から調べます
int[] reverseDigits = new int[digits.length-1];
for (int i = 0; i < digits.length - 1; i++) {reverseDigits[i] = digits[digits.length - 2 - i];
}
// 数列の和を 11 で割った余りを計算します
int remainder = 0;
for (int i = 0; i < 11; i++) {int p = reverseDigits[i];
int q = (i < 6) ? i + 2 : i - 4;
remainder += p * q;
}
remainder %= 11;
// 检查余数
return (remainder == 0 || remainder == 1) ? checkDigit == 0 : checkDigit == 11 - remainder;
}
}
TypeScript 实现
export function MyNumberValid(duodecupleDigits: string) {if (!/^\d{12}$/.test(duodecupleDigits)) return false;
const checkDigit = MyNumberCalcCheckDigit(duodecupleDigits.substring(0, 11));
return Number(duodecupleDigits[11]) === checkDigit;
}
/** 個人番号の 1~11 桁からチェックデジットを求める */
export function MyNumberCalcCheckDigit(p: string) {const q = [6, 5, 4, 3, 2, 7, 6, 5, 4, 3, 2];
if (!/^\d{11}$/.test(p)) return -1;
// Pn * Qn の合計値
const sumPnxQn = q.reduce((r, _, n) => r + Number(p[n]) * q[n], 0);
const mods = sumPnxQn % 11;
// (Pn * Qn) % 11 <= 1 のときチェックデジットは 0 とする
return mods <= 1 ? 0 : 11 - mods;
}
正文完