随着2023年12月初新版外国人永久居留证的发布,其证件信息进行了不少更新。新版证件号码跟二代身份证一样,为18位数字了,固定以9开头,跟老版外国人证号码并不能直接进行转换,但可通过读取证件芯片信息进行转换。本文将提供新版外国人永久居留证证件号码JS函数,实现新版外国人证件号码转换为旧版号码
/**
* 新老外国人永久居留证证件号码转换
* 通常是通过读取新版外国人证,通过里面芯片信息才能转换得到旧版外国人证
* @param newCardNo 新版外国人证号码
* @param newCardNation 新版外国人证民族,其实是国籍代码
* @param newCardRelatedItem 新版外国人证读卡芯片里的relatedItem信息
* @example
* ```js
* foreignCardFromNewToOld('932586198001010029', 'PAK', '010') // -> 'PAK320180010103'
* ```
*/
export function foreignCardFromNewToOld(
newCardNo: string = '',
newCardNation: string = '',
newCardRelatedItem: string = ''
): string {
if (!newCardNo || !newCardNation || !newCardRelatedItem) {
return '';
}
// 旧版外国人证前14位
const strOldCardNo14Chars: string = [
// 第1-3位,国籍
newCardNation,
// 第4-5位,首次申领地所属省行政区数字代码
newCardNo.slice(1, 3),
// 第6-7位,首次申领地所属市行政区数字代码
newCardRelatedItem.slice(0, 2),
// 第8-13位,6位的出生日期
newCardNo.slice(8, 14),
// 第14位,顺序吗
newCardRelatedItem.slice(2, 3),
].join('');
const resultDigit = calculateCheckDigitOldForeignCard(strOldCardNo14Chars);
if (!resultDigit.success) {
return '';
}
const strOldCardNoLastChar: string = resultDigit.result.toString();
return strOldCardNo14Chars + strOldCardNoLastChar;
}
/**
* 计算旧版外国人永居证的第15位校验位
* @param id 旧版外国人永居证的前14位
* @example
* ```javascript
* calculateCheckDigitOldForeignCard('PAK32018108031') // -> 2
* ```
*/
export function calculateCheckDigitOldForeignCard(id: string): {
success: boolean;
result?: number;
errorMsg?: string;
} {
if (id?.length !== 14) {
return { success: false, errorMsg: '计算校验外国人永居证第15位号段时,输入的证号长度应为14位。' };
}
if (!/[a-z]{3}[0-9]{11}/i.test(id)) {
return { success: false, errorMsg: '非有效输入,前3位必须为字母,后面为数字。' };
}
let sum = 0;
const weight = [7, 3, 1];
for (let i = 0; i < 14; i++) {
const char = id[i];
let charValue;
if (i < 3) {
// Convert latin letters to number according to the mapping
charValue = char.charCodeAt(0) - 'A'.charCodeAt(0) + 10;
} else {
charValue = Number(char);
}
sum += charValue * weight[i % 3];
}
// Use the remainder of the sum / 10 as the check digit
return { success: true, result: sum % 10 };
}