Files
simple_password/README.md
T
laoyang 9ca33a0328 docs(readme): 修正校验脚本调用方式,标注跨机器产物不可复现 (#2)
- 三个代码块补 `cd ../_tooling`:脚本不在仓库里,按 README 原来的写法
  (在仓库根目录直接 `node _sp_logo_export.js`)会 MODULE_NOT_FOUND
- 标注 docs/logo 的 PNG 与 docs 截图跨机器不可复现:Windows 重跑与已提交
  版本逐字节相同(10/10 一致),WSL 重跑则 10/10 全变、阴影版最大通道差 255,
  判据两边都是 95/95。先写清楚,免得下次当成脚本坏了去"修"
- 顺带记录 _sp_logo_export.js 改为按 __dirname 定位仓库(支持 SP_REPO 覆盖),
  不再写死 D:/ 或 /home/ 绝对路径
2026-10-29 14:59:52 +08:00

138 lines
6.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Simple Password
一个干净、纯本地的密码生成器。单文件 `index.html`,双击即用,也可丢到任意静态托管上。
**在线使用 → https://password.yangyq.net/**
![深色主题](./docs/dark.png)
## 特点
- **纯前端,零依赖** — 一个 `index.html`,没有构建步骤、没有 CDN、没有任何外部请求。断网可用。
- **左设置、右操作** — 设置栏在左,不调任何设置时视线直接落到右侧的密码与「复制密码」。窄屏自动变上下排列,设置在上。
- **密码学安全随机** — 走 `crypto.getRandomValues` + 拒绝采样消除取模偏差,不用 `Math.random()`。
- **生成即复制** — 默认开启自动复制;剪贴板 API 不可用(如 `file://` 下的旧浏览器)时自动降级到 `execCommand`。
- **深浅色** — 跟随系统偏好,可手动切换并记住选择。首帧前定主题,不会白屏闪一下。
- **可调长度** — 4~64 位。选了「每类至少一位」时,下限自动收紧到所选类型数。
- **四类字符可选** — 小写 / 大写 / 数字 / 符号,四类全不选会被兜回小写,不会生成空密码。
- **排除易混淆字符** — 一键去掉 `0 O o 1 l I`,抄写不出错。
- **自定义排除** — 想避开 `@`、空格或某个符号,直接填进去。
- **强度与熵** — 按 `长度 × log₂(字符池)` 算真实熵,分五档给出评价,同时显示字符池规模。
- **批量候选** — 一次出 5 个,点任意一条即复制。
- **不保留记录** — 不记历史,`localStorage` 只存偏好设置与主题,不存密码。
## 界面
设置与主操作分居左右两栏 —— 不调设置的人,视线直接落到右侧的密码和「复制密码」上。
「复制密码」与「换一个」严格等大(实测 241×42,宽高差 0px),用渐变与实心填充区分主次。
浅色主题:
![浅色主题](./docs/light.png)
移动端自动转为上下单列,设置在输出之上:
<img src="./docs/mobile.png" alt="移动端" width="320">
## 使用
直接用浏览器打开 `index.html` 即可,无需服务器。
已经部署的在线版本:<https://password.yangyq.net/>
想在本地用 http 协议(例如需要真实剪贴板权限时):
```bash
python -m http.server 8000
# 然后访问 http://127.0.0.1:8000/
```
## 快捷键
| 键 | 作用 |
|---|---|
| `空格` | 换一个密码 |
| `C` | 复制当前密码 |
| `点击密码` | 也可以复制 |
在输入框里打字时不会误触发。
## 关于安全
- 所有运算在浏览器里完成,**不联网、不上传、不写日志**。
- 用 `crypto.getRandomValues` 取随机数,并按「拒绝采样」丢弃落在偏置区间的值,避免取模带来的分布倾斜。
- 勾「每类至少一位」时,先从每类各取一位,剩余位从全池随机,最后整体洗牌 —— 保证覆盖的同时不引入位置可预测性。
- **不保留任何生成记录**。密码只存在于剪贴板与页面显示,刷新即失去痕迹;`localStorage` 里只存偏好设置与主题,不存密码。
## 浏览器支持
Chrome / Edge / Firefox / Safari 的近两年版本,以及移动端浏览器。
用到 `backdrop-filter`(毛玻璃)和 `crypto.getRandomValues`,老浏览器上会自动降级为不透明背景,功能不受影响。
## 目录
```
index.html 全部内容:结构、样式、脚本
docs/ README 用的界面截图
logo/ 品牌 logo 多尺寸 PNG(5 档 × 带阴影/无阴影)
```
`docs/logo/` 里的图**只进仓库、不部署到站点**(`_sp_deploy.sh` 只覆盖 `index.html`),
所以线上访问 `https://password.yangyq.net/docs/logo/logo-1024.png` 会 404 —— 这是预期行为。
重新导出 logo(脚本在仓库外的 `_tooling/`,需要 `playwright` + `Pillow`)。
**先 `cd _tooling/` 再跑**,脚本按 `__dirname/../simple_password` 定位仓库:
```bash
cd ../_tooling
node _sp_logo_export.js # 输出到 docs/logo/:logo-{64,128,256,512,1024}[-flat].png
python3 _sp_logo_verify.py # 像素判据 95 项:白边比例 / 主体居中 / 阴影朝向 / 圆角
python3 _sp_logo_verify_falsify.py # 反证 6 条:证明上面那套判据抓得住 bug
```
> ⚠️ **不要在不同机器上重跑覆盖仓库里的 PNG**。仓库里这 10 张是在 Windows 侧生成的,
> 换到 WSL(或另一台机器)重跑,字体度量与阴影模糊实现不同,产物**逐字节全不一样**
> —— 实测 10/10 文件 md5 全变,阴影版最大通道差到 255。判据仍是 95/95 通过、
> 几何关系一致,但 diff 会是一大堆无法 review 的二进制变更。真要重跑就接受这一点,
> 别把它当成"脚本坏了"。
尺寸是 64/128/256/512/1024 五档,每档两版:`logo-N.png` 带品牌阴影(用于展示场合)、
`logo-N-flat.png` 无阴影(用于 favicon、深色底、贴边摆放)。画布是正方形,
白边控制在 shadow 8% / flat 3%(旧版 41%)。
## 开发校验
改完 `index.html` 后建议跑一遍(脚本在仓库外的 `_tooling/`,配合 `jsdom` 与 `playwright`):
```bash
cd ../_tooling
node _sp_test.js # 功能判据(jsdom,78 条)
node _sp_visual.js # 真实浏览器几何 / 对比度 / 多视口(114 条)
node _sp_clip.js # 真实剪贴板端到端(19 条)
node _sp_file_check.js # file:// 双击直开(15 条)
node _sp_falsify.js # 反向注入,证明功能判据有牙齿(22 条)
node _sp_visual_falsify.js # 反向注入,证明几何判据有牙齿(6 条)
```
反向注入必须单独跑视觉那套:`_sp_falsify.js` 只喂 `_sp_test.js`(jsdom 不做布局),
把「按钮等大」「两栏左右」这类几何 bug 注进去根本影响不到被测判据,
会表现成"注入后仍全绿",看着像判据没牙齿,其实是靶子选错。
重拍 README 截图:
```bash
cd ../_tooling
node _sp_shots.js # 输出到仓库 docs/:dark.png / light.png / mobile.png
node _sp_shot_verify.js # 断言被截图的那个页面状态是对的(26 条)
```
> ⚠️ 截图同样是**跨机器不可复现**的:手机视口实测 Windows 780×2490、WSL 780×2510,
> 字体度量差异导致高度不同。判据只断言几何关系,别断言绝对页高,也别拿另一侧的图覆盖仓库。
> 截图脚本与判据脚本分开,是因为判据脚本的截图(`_sp_shots` 目录)尺寸与时机跟着判据走,
> 会带 toast、焦点框、320px 极端视口;README 需要的是干净的产品图。混在一起改判据就会把图搞脏。
## License
MIT