// 随机密码工具:生成强度较高且便于输入的密码 // 字符集排除易混淆字符(0/O/o/1/l/I),避免用户手动输入时出错 const UPPER = 'ABCDEFGHJKLMNPQRSTUVWXYZ' const LOWER = 'abcdefghijkmnpqrstuvwxyz' const DIGIT = '23456789' const CHARSET = UPPER + LOWER + DIGIT /** 生成指定长度的随机密码,默认 12 位,保证同时包含大小写字母与数字 */ export function generateRandomPassword(length = 12): string { const size = Math.max(6, length) const chars: string[] = [randomChar(UPPER), randomChar(LOWER), randomChar(DIGIT)] // 补齐剩余位数后打乱,避免固定位置出现固定字符类型 while (chars.length < size) { chars.push(randomChar(CHARSET)) } return shuffle(chars).join('') } /** 从字符集中安全随机取一个字符 */ function randomChar(charset: string): string { return charset[secureRandomInt(charset.length)] } /** 使用 crypto 生成 [0, max) 的随机整数,crypto 不可用时回退 Math.random */ function secureRandomInt(max: number): number { if (typeof crypto !== 'undefined' && typeof crypto.getRandomValues === 'function') { // 取整倍数区间拒绝采样,避免取模带来的分布偏差 const limit = Math.floor(0xffffffff / max) * max const buffer = new Uint32Array(1) let value = 0 do { crypto.getRandomValues(buffer) value = buffer[0] } while (value >= limit) return value % max } return Math.floor(Math.random() * max) } /** Fisher-Yates 洗牌 */ function shuffle(arr: string[]): string[] { for (let i = arr.length - 1; i > 0; i--) { const j = secureRandomInt(i + 1) const tmp = arr[i] arr[i] = arr[j] arr[j] = tmp } return arr }