使用方法
- 「密码长度」默认填 12(示例值),允许 8~64 之间的整数;「生成数量」默认填 15(示例值),允许 1~50 条。
- 字符类别默认勾选 大写字母、小写字母、数字 三类,符号默认不勾——部分企业内网登录页、路由器管理页和 POS 终端键盘对
!#%&的输入处理不一致,默认关掉能少踩一次坑。 - 保持「剔除相似字符 0Oo1Il」勾选,字符池会由 62 位降到 56 位,10 位十进制以下的信息量损失在第 3 节有具体数字。
- 点「生成密码」,或直接在长度、数量输入框里按 Enter。结果表每一行右侧会出现一条 5 格强度条,格数越多档位越高。
- 结果表默认先显示 12 行,点「加载更多」每次追加 12 行;需要带走时用「复制全部」(一行一条密码)、「导出 CSV」(带 BOM,Excel 打开中文不乱码)或「复制对照表」(制表符分隔,可直接粘进表格)。
这个随机密码生成器能解决什么问题
一是默认值直接可用。很多工具默认把四类字符全勾上,生成的密码里带 *、^,粘进只接受字母数字的旧系统里直接报错。本页默认只开三类字符,需要符号时自己勾,少一次「生成—被拒—改设置—再生成」的来回。
二是一次拿到一批,且每条都满足类别要求。生成时先给每个已勾选的类别各抽一个字符,再用整个字符池补足长度,最后整体洗牌。这样抽出来的每一条都天然含大写、小写、数字各至少一个,不会被「密码必须同时包含字母和数字」这类注册校验打回。
三是把「这条密码到底算不算强」变成看得见的东西。结果表右侧的强度条把 5 个档位画在一行里,同一批密码一眼扫过去就知道当前设置落在哪一档;调长度、加类别时条子会当场伸长,比记住一串 bit 数直观。
四是方便把结果搬进别的地方。给一批设备写初始口令、给测试库造账号、给 CSV 批量导入准备凭据时,用「导出 CSV」拿到带 BOM 的表格文件,或者用「复制对照表」把整张表贴进 Excel,不用一条条选中复制。
本页不做这些事:不保存密码(不写 localStorage、不发任何网络请求)、不去查这条密码有没有出现在历史泄露库里、也不做「密码短语」那种用常见单词拼长口令的事。想评估一条已有密码的强弱,请用页面底部的「密码力量检测」。
生成原理:字符类别、字符池与拒绝采样
1)随机数从哪来。取值只有一行:crypto.getRandomValues(new Uint32Array(1))。它是 W3C Web Cryptography API 定义的加密随机接口,由浏览器直接向操作系统熵池要数,不是 Math.random() 那种内部状态可推导的伪随机序列。RFC 4086《Randomness Requirements for Security》给出的结论是安全凭据必须建立在不可预测的随机源上,用时间戳、进程号、自增计数器拼出来的「随机」在攻击者眼里基本等于可枚举。全站 2000 多个工具里,只有生成凭据的页面必须走这个接口。
2)为什么必须做拒绝采样。拿到一个 32 位无符号整数后,最省事的写法是 n % 池大小。但当池是 56 位时,2³² = 4294967296 不能被 56 整除:4294967296 ÷ 56 = 76695844 余 32。余数落在 0~31 的随机数比落在 32~55 的多出现一次,一些字符被抽中的概率会高出约 32 / 4294967296 = 7.45×10⁻⁹ 的相对偏差——数值很小,但它是结构性偏差,不会因为抽得多而消失。本工具的做法是先算出接受上限 Math.floor(4294967296 / 56) × 56 = 4294967264,随机数一旦落在 4294967264~4294967295 这 32 个值上就丢弃重抽。
3)为什么用 32 位而不是 8 位字。拒绝率和字宽直接相关。同样池 56 位,改用 Uint8Array 时接受上限是 256 − (256 % 56) = 224,要丢掉 32 个取值,拒绝率高达 12.5%,等于每 8 次取数就有 1 次白跑;换成 32 位字后丢弃比例降到 7.45×10⁻⁹,肉眼完全看不出停顿。池换成 62 位(不剔除相似字符)时,单字节方案的拒绝率也有 3.125%,32 位方案则是 9.31×10⁻¹⁰。
4)字符池怎么算出来的。大写字母 26 个、小写字母 26 个、数字 10 个、常用符号 12 个(!@#$%^&*_-+=)。「剔除相似字符」会从池里去掉 0 O o 1 I l 这 6 个字符,其中大写贡献 O I、小写贡献 o l、数字贡献 0 1,符号集里一个都没有。所以默认三类字符是 26 + 26 + 10 = 62 位,剔除后 56 位;四类全勾是 74 位,剔除后 68 位。
5)强度条怎么分档。把取值空间写成十进制,位数记为 d,取 d = floor(长度 × log₁₀(字符池))——也就是「猜中需要试多少个十进制的数」。池 56 位时 log₁₀56 = 1.748188,长度 12 位对应 d = floor(12 × 1.748188) = floor(20.9783) = 20。分档阈值取 8 / 12 / 16 / 24 四个整数关口:d 小于 8 判 1 格「弱」,8 到 11 判 2 格「一般」,12 到 15 判 3 格「强」,16 到 23 判 4 格「很强」,24 及以上判 5 格「极强」。这四个关口对应的是「秒级可穷举」「小时内可穷举」「需要专门算力」「需要大型集群」四道台阶,而不是随手切的等分。
6)洗牌用的是 Fisher–Yates。先把每个类别的强制位放进数组,补足长度后整体洗牌,从末位往前遍历、与前面随机一位交换。常见写法 sort(() => Math.random() - 0.5) 在多数 JS 引擎里会因为比较函数不满足传递性而退化成偏差明显的伪洗牌——如果用它,强制位就容易扎堆在开头,密码的形态一眼可辨。
完整示例(默认设置,数值仅作演示)
下面这套条件就是这个随机密码生成器打开时的默认值:长度 12 位、数量 15 条、勾选大写字母 + 小写字母 + 数字、勾选剔除相似字符,字符池 56 位。
- 字符池:26(大写) + 26(小写) + 10(数字) = 62,再减去
0 O o 1 I l六个字符,得 56 位; - 取值空间:
56¹² = 9.51×10²⁰种,写成十进制是 20.9783 位; - 十进制位数 d = 20,落在 16~23 区间,强度条显示 很强(4/5 格);
- 按每秒试 10¹² 条算,穷举一半要 15.1 年;攻击者如果只有每秒 10⁹ 条的算力,则需要 1.51×10⁴ 年;
- 15 条完全互不相同的概率约
1 − 1.10×10⁻¹⁹,实际上可以认为必然不重复。
把长度从 12 位调到 16 位,d 立刻从 20 跳到 27,强度条从 4 格涨到 5 格;再把长度调回 8 位,d 掉到 13,条子只剩 3 格。这条条子跟的就是长度 × 字符池,不看具体字符——它衡量的是「猜中的难度」,衡量不了「这条密码会不会被钓鱼页骗走」。
字符类别与长度对照表
下表固定长度为 12 位,逐档改变勾选的字符类别,用来回答「少勾一类会掉多少」:
| 勾选的字符类别(长度固定 12 位) | 字符池 | 取值空间 | d | 强度档位 |
|---|---|---|---|---|
| 只勾「数字」 | 8 位 | 6.87×10¹⁰ | 10 | 一般(2/5) |
| 只勾「小写字母」 | 24 位 | 3.65×10¹⁶ | 16 | 很强(4/5) |
| 勾「大写 + 小写」 | 48 位 | 1.50×10²⁰ | 20 | 很强(4/5) |
| 勾「大写 + 小写 + 数字」(默认) | 56 位 | 9.51×10²⁰ | 20 | 很强(4/5) |
| 四类全勾(含常用符号) | 68 位 | 9.77×10²¹ | 21 | 很强(4/5) |
再看固定字符池 56 位、只改长度的那张表。它说明一件事:加长度比加字符类别划算得多——从 12 位加到 16 位,d 涨 7;把字符从三类加到四类,d 只涨 1。
| 密码长度(池固定 56 位) | 取值空间 | d | 强度档位 | 每秒 10¹² 次穷举一半 |
|---|---|---|---|---|
| 8 位 | 9.67×10¹³ | 13 | 强(3/5) | 48.4 秒 |
| 10 位 | 3.03×10¹⁷ | 17 | 很强(4/5) | 1.8 天 |
| 12 位(默认) | 9.51×10²⁰ | 20 | 很强(4/5) | 15.1 年 |
| 16 位 | 9.35×10²⁷ | 27 | 极强(5/5) | 1.48×10⁸ 年 |
| 20 位 | 9.20×10³⁴ | 34 | 极强(5/5) | 1.46×10¹⁵ 年 |
| 24 位 | 9.05×10⁴¹ | 41 | 极强(5/5) | 1.43×10²² 年 |
第三张表是拒绝采样的取舍,说明为什么代码里用的是 32 位字而不是单字节:
| 字符池 | 单字节 Uint8Array 接受上限 | 单字节拒绝率 | 32 位字接受上限 | 32 位字拒绝率 |
|---|---|---|---|---|
| 56 位(默认) | 224 | 12.5% | 4294967264 | 7.45×10⁻⁹ |
| 62 位(不剔除相似字符) | 248 | 3.125% | 4294967292 | 9.31×10⁻¹⁰ |
| 68 位(四类全勾并剔除) | 204 | 20.313% | 4294967244 | 1.21×10⁻⁸ |
输入范围、边界与强度条档位说明
下面这些不是随便定的限制,知道它们能避免把这页当万能工具用:
- 长度 8~64 的整数。下限 8 是因为池 56 位时 8 位只有 d = 13、每秒 10¹² 次 48.4 秒就能穷举完;上限 64 是因为多数业务系统的口令字段按 64 字节存,再往上填了也存不下。小数、字母、空值都会被拒绝,不会静默按 0 处理。
- 数量 1~50。数量只决定一次输出几条,不改变任何一条的强度。默认 15 条是为了让「加载更多」这件事在打开页面时就能被看见;上限 50 是防止一次把结果表撑爆。
- 「每类至少出现一次」永远成立。长度下限是 8,而字符类别一共只有 4 类,8 已经大于 4。但工具里仍保留了
长度 < 已勾选类别数的兜底判断,万一以后把下限往下调,它会立刻报错而不是悄悄丢掉某一类。 - 只勾「数字」也能生成,但那不是好主意。数字池剔除
01后只剩 8 个字符,12 位的 d 只有 10,强度条只亮 2 格。类别勾得越少,条子越短。 - 强度条是「设置」的属性,不是「这一条」的属性。同一批密码的 d 完全相同,因为 d 只由池大小和长度决定,所以这个随机密码生成器给同一次设置下的每一条都画一样的格数。这也是为什么条子长不等于绝对安全:密码如果被键盘记录器截获、被钓鱼页拿到,或者你在十几个站点复用同一条,再长的条子也挡不住。
- 首屏那 3 条「示例展示」不是随机生成的,只是写在 HTML 里的演示文本,用来告诉你结果长什么样。点一次「生成密码」之后显示的才是真正来自
crypto.getRandomValues的结果。 - 导出的 CSV 带 BOM,复制出来的表格不带。CSV 文件前面加了
U+FEFF字节序标记,Excel 双击打开不会把中文表头显示成乱码;而经剪贴板复制的文本不能带 BOM,否则粘进某些解析器会在第一个字段里多出一个不可见字符。
常见问题
为什么默认不勾「常用符号」?
因为大部分密码用在登录框里,而符号在不少终端上会被「吃掉」——POS 机键盘、路由器管理页的旧版输入框、部分企业 SSO 页面会把 & 或 # 当成转义字符。默认关掉符号、需要时自己勾,比生成完才发现登不上去再回来改要省事。真要高强度账号,加长度比加符号划算:池从 56 涨到 68,d 只涨 1。
生成的密码会重复吗?点两次会不会拿到同一批?
12 位默认设置下两条完全相同的概率约为 1 / 9.51×10²⁰;一批 15 条里任意两条撞车的概率约 1.10×10⁻¹⁹,实际可以认为不会重复。每次点按钮都是一次全新的抽取,工具不缓存上一次的结果,所以前后两批之间同样不会互相干扰。
为什么剔除相似字符只让字符池少了 6 位,强度条却几乎不动?
因为 d 是对数尺度。池从 62 位降到 56 位,单字符的信息量从 log₂62 = 5.954 bit 落到 log₂56 = 5.807 bit,每位差 0.147 bit;12 位一共少 1.76 bit。换成十进制位数只是从 21 位降到 20 位,两个都落在「很强」区间,所以条子的格数不变。剔除相似字符买到的是人工抄写不易出错,代价小到可以忽略。
强度条的五个档位是按什么切的?
按十进制位数 d:小于 8 是「弱」(1 格),8~11 是「一般」(2 格),12~15 是「强」(3 格),16~23 是「很强」(4 格),24 及以上是「极强」(5 格)。四个关口分别对应「一台笔记本秒级穷举」「小时内穷举」「需要 GPU 集群」「需要国家级算力」。切法是按穷举成本的数量级定的,不是等分。
「每类至少出现一次」是怎么做到的?
生成一条密码分两步:先按你勾选的每一个类别各抽一个字符放进数组(保证类别齐全),再用整个字符池补足到指定长度,最后用 Fisher–Yates 把整个数组洗一遍。洗牌这一步很关键——如果省略它,每个类别的那个「代表字符」会一直待在数组开头,密码的形态一眼就能看出来。
导出的 CSV 和「复制对照表」有什么区别?
两者内容一样(序号、密码、十进制位数、强度档位),差别在编码和分隔符。CSV 是文件,编码 UTF-8 并加了 BOM,Excel 双击打开不乱码,字段用逗号分隔;「复制对照表」走剪贴板,用制表符分隔且不带 BOM,适合直接粘进已经打开的表格或数据库客户端。密码里不含逗号和制表符,所以两种格式都不会串列。
可以用它生成接口 token、临时口令吗?
可以,但要注意 token 的字符集限制。URL 里用的 token 如果混进 + / = 这些字符,放到 query string 里需要额外做百分号编码,否则会被截断。这类场景建议只勾「大写字母 + 小写字母 + 数字」,再把长度提到 32 位,得到的就是纯字母数字串,任何传输层都不用再转义。
页面会把生成的密码上传或保存下来吗?
不会。随机数由 crypto.getRandomValues 提供,拼接、剔字符、洗牌、渲染全在当前页面完成,没有任何网络请求;也没有写 localStorage 或 sessionStorage,刷新即丢。想自己验证,打开开发者工具的 Network 面板,点几次「生成密码」,看不到任何新请求发出。
相关工具
- 密码力量检测:评估一条已有密码被猜中的难易,会看字符集、常见词和重复模式,跟本页「生成时选档位」是反过来的用法。
- 随机A-Z字母生成器:只要字母、不要数字时的专用入口,适合给测试数据造字母串。
- 随机符号生成器:单独抽符号串,用来测输入框对特殊字符的过滤规则。
- 随机折扣代码生成器:生成短码形态的随机串,格式固定为字母数字组合。
- 随机顺序ID生成器:生成带序号感的随机 ID,适合做订单号、单据号这类可读编号。
- 随机主机名生成器:批量造主机名、设备名,常和本页配合给设备配初始口令。
- 随机信用卡卡号生成器:生成通过 Luhn 校验的测试卡号,只能在测试环境用。
- 随机工具:查看全部随机工具。