ts-pinblock
Version:
75 lines • 3.18 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.arr2hex = exports.pinblock = void 0;
/**
* pinblock长度8对应的是算法是DES/3DES 算法,长度16对应的算法是:SM4 算法
* @param pin pin值
* @param pan pan 在银行一般是用户的卡号
* @param pbl pinblock的长度,是8还是16位,默认8位。
*/
exports.pinblock = (pin, pan = '', pbl = 8) => {
// pin是4到12位的纯数字
if (pin.length < 4 || pin.length > 12) {
return null;
}
if (!/^\d+$/.test(pin)) {
return null;
}
// pin的编码格式为:
// pin的字节长度为8个字节
// 第一个字节是pin的长度
// 后面每个字节是每2个pin码填1个字节,每个pin占4位
// 没有填满的用0xff补充
// 比如pin码是123456,对应的pin码内存为:0x06 0x12 0x34 0x56 0xFF 0xFF 0xFF 0xFF
const pinBuffer = new ArrayBuffer(pbl);
const pinAfterProcess = new Uint8Array(pinBuffer);
pinAfterProcess[0] = pin.length; // 第一个字节为pin的长度
let offiset = 0;
// 如果pin的长度不够,那么每一位都补齐F
if (pin.length < pbl * 2 - 2) {
pin += String('F').repeat(pbl * 2 - 2 - pin.length);
}
for (let i = 0; i < pin.length; i = i + 2) {
offiset = i / 2 + 1;
pinAfterProcess[offiset] = ((parseInt(pin[i], 16) & 0x0f) << 4) | (parseInt(pin[i + 1], 16) & 0x0f); // 如果是基数的长度,那么后面4个位都是1,相当于数字15
}
// 如果没有pan,那么直接返回pin的结果。
if (pan === '') {
return pinAfterProcess;
}
let panStr = `0000${pan.substr(pan.length - 12 - 1, 12)}`; // 从最右边的13位开始,获取12个字符,因为不能包括最右边的校验位。
// 如果panStr没有16位,那么在最左边用0补齐。
if (panStr.length < pbl * 2) {
panStr = String('0').repeat(pbl * 2 - panStr.length) + panStr;
}
// pan的buffer的长度为8,panStr的长度为16,每2个字符写入到一个字节,每个字符分别占前后四位。
const panBuffer = new ArrayBuffer(pbl);
const panAfterProcess = new Uint8Array(panBuffer);
for (let i = 0; i < panStr.length; i = i + 2) {
panAfterProcess[i / 2] = ((parseInt(panStr[i], 10) & 0x0f) << 4) | (parseInt(panStr[i + 1], 10) & 0x0f);
}
const pinBlockBuffer = new ArrayBuffer(pbl);
const pinBlock = new Uint8Array(pinBlockBuffer);
for (let i = 0; i < pbl; ++i) {
pinBlock[i] = pinAfterProcess[i] ^ panAfterProcess[i]; // pinblock的长度为8,每个字节是pin和pan的异或结果。
}
return pinBlock;
};
function decimalToHex(d, padding = 2) {
var hex = Number(d).toString(16).toUpperCase();
padding = typeof padding === 'undefined' || padding === null ? (padding = 2) : padding;
while (hex.length < padding) {
hex = '0' + hex;
}
return '0x' + hex;
}
function arr2hex(arr) {
const t = [];
arr.forEach((item) => {
t.push(decimalToHex(item));
});
return t;
}
exports.arr2hex = arr2hex;
exports.default = exports.pinblock;
//# sourceMappingURL=index.js.map