dasdasd
This commit is contained in:
parent
26988d3de8
commit
fe15b877ab
@ -7,10 +7,25 @@ const CARD_TYPES = {
|
||||
unionpay: {
|
||||
name: '中国银联 (UnionPay)',
|
||||
// 固定前缀(用户提供的成功案例都是这个前缀)
|
||||
prefix: '622836754',
|
||||
prefix: '622836754', // 固定BIN前缀
|
||||
length: 16,
|
||||
cvvLength: 3,
|
||||
useLuhn: true // 使用Luhn算法校验
|
||||
useLuhn: true,
|
||||
|
||||
// 成功案例的后7位模式(用于智能生成)
|
||||
successfulPatterns: [
|
||||
'5055812', '8774419', '6781457', '2738949',
|
||||
'2602400', '8575105', '6496080', '0057649',
|
||||
'9574719', '8435128', '2797374', '5956423',
|
||||
'7237848', '0385107', '4252006', '7562054'
|
||||
],
|
||||
|
||||
// 生成策略配置
|
||||
generation: {
|
||||
mutationRate: 0.5, // 50% 使用变异策略
|
||||
randomRate: 0.5, // 50% 使用纯随机
|
||||
mutationDigits: [1, 2] // 变异时改变1-2个数字
|
||||
}
|
||||
},
|
||||
visa: {
|
||||
name: 'Visa',
|
||||
|
||||
@ -13,7 +13,7 @@ class CardGenerator {
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成卡号
|
||||
* 生成卡号(混合策略:变异真实案例 + 纯随机)
|
||||
* @param {string} type - 卡类型
|
||||
* @returns {string}
|
||||
*/
|
||||
@ -23,28 +23,93 @@ class CardGenerator {
|
||||
throw new ValidationError('card-generator', `Unknown card type: ${type}`);
|
||||
}
|
||||
|
||||
const { length, useLuhn } = config;
|
||||
const { prefix, length, useLuhn, successfulPatterns, generation } = config;
|
||||
|
||||
// 支持多个前缀(随机选择)或单个前缀
|
||||
let prefix;
|
||||
if (Array.isArray(config.prefixes)) {
|
||||
// 从数组中随机选择一个前缀
|
||||
const randomIndex = randomInt(0, config.prefixes.length - 1);
|
||||
prefix = config.prefixes[randomIndex];
|
||||
} else {
|
||||
// 兼容旧配置(单个prefix)
|
||||
prefix = config.prefix;
|
||||
// 如果有成功案例和生成策略配置,使用混合策略
|
||||
if (successfulPatterns && generation) {
|
||||
const useMutation = Math.random() < generation.mutationRate;
|
||||
|
||||
if (useMutation) {
|
||||
// 策略1:基于真实案例变异
|
||||
return this.generateByMutation(prefix, successfulPatterns, generation.mutationDigits);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 策略2:纯随机生成(默认或回退)
|
||||
if (useLuhn) {
|
||||
// 使用Luhn算法生成
|
||||
return generateLuhnNumber(prefix, length);
|
||||
} else {
|
||||
// 纯随机生成
|
||||
const remainingLength = length - prefix.length;
|
||||
return prefix + randomDigits(remainingLength);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 基于真实案例变异生成卡号
|
||||
* @param {string} prefix - BIN前缀
|
||||
* @param {Array} patterns - 成功案例的后7位
|
||||
* @param {Array} mutationDigits - 变异数字个数[min, max]
|
||||
* @returns {string}
|
||||
*/
|
||||
generateByMutation(prefix, patterns, mutationDigits) {
|
||||
// 随机选择一个成功案例
|
||||
const basePattern = patterns[randomInt(0, patterns.length - 1)];
|
||||
|
||||
// 随机决定改变几个数字
|
||||
const changeCount = randomInt(mutationDigits[0], mutationDigits[1]);
|
||||
const mutated = basePattern.split('');
|
||||
|
||||
// 改变指定数量的数字
|
||||
const changedPositions = new Set();
|
||||
for (let i = 0; i < changeCount; i++) {
|
||||
let pos;
|
||||
do {
|
||||
pos = randomInt(0, mutated.length - 1);
|
||||
} while (changedPositions.has(pos)); // 避免重复位置
|
||||
|
||||
changedPositions.add(pos);
|
||||
|
||||
// 生成不同的数字
|
||||
let newDigit;
|
||||
do {
|
||||
newDigit = randomInt(0, 9).toString();
|
||||
} while (newDigit === mutated[pos]);
|
||||
|
||||
mutated[pos] = newDigit;
|
||||
}
|
||||
|
||||
// 组合前缀和变异后的后7位(去掉最后一位校验位)
|
||||
const prefix15 = prefix + mutated.join('').slice(0, -1);
|
||||
|
||||
// 重新计算Luhn校验位
|
||||
const checkDigit = this.calculateLuhnCheckDigit(prefix15);
|
||||
|
||||
return prefix15 + checkDigit;
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算Luhn校验位
|
||||
* @param {string} partial - 不含校验位的卡号
|
||||
* @returns {string}
|
||||
*/
|
||||
calculateLuhnCheckDigit(partial) {
|
||||
let sum = 0;
|
||||
let isEven = true;
|
||||
|
||||
for (let i = partial.length - 1; i >= 0; i--) {
|
||||
let digit = parseInt(partial[i]);
|
||||
|
||||
if (isEven) {
|
||||
digit *= 2;
|
||||
if (digit > 9) digit -= 9;
|
||||
}
|
||||
|
||||
sum += digit;
|
||||
isEven = !isEven;
|
||||
}
|
||||
|
||||
return ((10 - (sum % 10)) % 10).toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成有效期
|
||||
|
||||
Loading…
Reference in New Issue
Block a user