遊戲點數卡、禮品卡、優惠券等需大量生成唯一「卡號+密碼」組合,要求不重複、可驗證、可匯入資料庫。
function generateCardsV1($batch, $ym, $quantity, $point) {
$cards = [];
for ($i = 1; $i <= $quantity; $i++) {
// 卡號:批次(2碼) + 年月(4碼) + 流水號(6碼) = 12碼
$sn = sprintf("%02d%04d%06d", $batch, $ym, $i);
// 密碼種子:三組 4 位隨機數
$seed = mt_rand(0, 9999) . mt_rand(0, 9999) . mt_rand(0, 9999);
$start = mt_rand(0, 20);
$pwd = strtoupper(substr(md5($seed), $start, 12));
// 避免視覺混淆:O→字母、0→字母
$pwd = str_replace('O', chr(mt_rand(65, 78)), $pwd);
$pwd = str_replace('0', chr(mt_rand(65, 78)), $pwd);
$cards[] = [
'sn' => $sn,
'password' => $pwd,
'point' => $point,
'created' => time()
];
}
return $cards;
}
// 使用:生成 1 萬張 (實際迴圈 100 萬次,示範用)
$cards = generateCardsV1(10, 2405, 10000, 100);
優點:卡號有序、可推導批次/時間、無需額外去重。
缺點:密碼若需極高熵值,MD5 截取 12 字元可能不足。
function generateCardsV2($count = 100, $snLen = 16, $pwdLen = 10) {
$numChars = range('0', '9');
$pwdChars = array_merge($numChars, range('A', 'Z')); // 0-9, A-Z
$cards = [];
while (count($cards) < $count) {
$sn = '';
for ($i = 0; $i < $snLen; $i++) $sn .= $numChars[array_rand($numChars)];
$pwd = '';
for ($i = 0; $i < $pwdLen; $i++) $pwd .= $pwdChars[array_rand($pwdChars)];
$key = $sn . '|' . $pwd;
if (!isset($cards[$key])) {
$cards[$key] = ['sn' => $sn, 'pwd' => $pwd];
}
}
return array_values($cards);
}
優點:程式碼簡短、字元集可自訂、密碼熵值高。
缺點:大量生成時 while 迴圈可能因碰撞變慢;需額外去重機制。
UNIQUE KEY uk_sn (sn),入庫時捕獲 23000 錯誤碼重試。INSERT IGNORE 或 ON DUPLICATE KEY UPDATE 降低交易開銷。password_hash() (bcrypt/argon2) 或至少 sha256($pwd . $salt)。random_int() (PHP 7+) 取代 mt_rand() 獲得密碼學安全隨機數。