我给自己写了一个本地密码生成器:随机、可读、用完不留痕

举报
yd_294377644 发表于 2026/11/07 19:50:02 2026/11/07
【摘要】 注册不同服务时,我总在“密码太简单”和“规则太复杂”之间来回折腾。在线生成器又可能记录输入或强推云端保存,于是我用 Python 写了一个本地密码生成器,支持随机密码、可读口令、强度提示和自动清除剪贴板。这篇博客记录随机源选择、字符规则、熵估算以及敏感内容处理中的几个关键取舍。

目录

  1. 缘起:密码管理最烦的不是记不住
  2. 需求拆解:生成出来还要适合使用
  3. 技术选型:安全随机源比漂亮界面重要
  4. 核心实现一:生成真正不可预测的字符
  5. 核心实现二:可读口令与强度评估
  6. UI 定制:敏感内容不应该停留太久
  7. 三个密码工具容易给人的错误安全感
  8. 结尾:生成器只负责随机,保管仍然需要边界

1. 缘起:密码管理最烦的不是记不住

我以前设置密码时经常陷入一个循环:先想一个容易记的词,再补数字和符号;网站提示不符合规则,就继续加字符;下次忘记时,又只能点“忘记密码”。

常见的在线密码生成器看起来很方便,但我始终有几个顾虑:

  • 生成的密码可能经由网页脚本或接口传到服务器;
  • 页面会把密码历史、收藏和同步作为主要卖点;
  • 复杂字符虽然强,却不一定能顺利输入到所有设备;
  • 生成后复制到剪贴板,过很久仍然留在那里。

我需要的不是一个“密码保险箱”,而是一个临时工具:本地生成、参数透明、复制后自动清理,不替我保存主密码,也不把安全责任包装成一个分数。

2. 需求拆解:生成出来还要适合使用

我把工具拆成两种生成方式:完全随机密码适合重要账户,可读口令适合需要手动输入的临时场景。

诉求(人话) 拆解后(可验收)
随机性可靠 使用操作系统安全随机源,不使用时间或普通伪随机数
规则清楚 可设置长度、字符集和是否排除易混字符
手动输入方便 支持由本地词表生成的多词口令
知道强不强 显示长度、字符空间和估算熵,不假装绝对安全
复制后少留痕 提供剪贴板自动清除倒计时
不被意外保存 默认不保存生成历史、配置中的密码和日志

工具不会检查“这个密码是否曾经泄露”,因为那需要把密码发送给外部服务或维护一份不可能完整的泄露库。它只负责生成和解释,不冒充在线安全检测平台。

心得:安全工具最重要的功能之一,是明确告诉用户它没有做什么。

3. 技术选型:安全随机源比漂亮界面重要

程序使用 Python 和 tkinter,核心随机能力来自标准库 secrets:

能力 方案
安全随机字符 secrets.choice()
随机字节 secrets.token_bytes()
可读口令 本地词表 + secrets.choice()
字符串校验 string 与自定义规则
剪贴板操作 tkinter
配置保存 只保存非敏感偏好

我没有使用 random 模块生成密码。普通伪随机数适合模拟和抽样,不应该承担凭据生成任务。随机种子、当前时间和进程信息都不应成为密码的主要不可预测性来源。

词表也随程序一起保存在本地,不从网络动态下载。词表内容可以公开,真正的随机性来自安全随机选择以及足够的组合空间。

4. 核心实现一:生成真正不可预测的字符

字符集由用户选择,但每个字符都通过 secrets.choice 抽取。为了避免生成结果恰好缺少某一类字符,程序先从选中的每个类别中抽取至少一个,再打乱全部字符。

import secrets
import string

def build_password(length, use_upper, use_digits, use_symbols):
    groups = [string.ascii_lowercase]

    if use_upper:
        groups.append(string.ascii_uppercase)
    if use_digits:
        groups.append(string.digits)
    if use_symbols:
        groups.append("!@#$%^&*_-+=")

    if length < len(groups):
        raise ValueError("长度不足以覆盖已选择的字符类别")

    required = [secrets.choice(group) for group in groups]
    alphabet = "".join(groups)
    remaining = [secrets.choice(alphabet) for _ in range(length - len(required))]
    result = required + remaining
    secrets.SystemRandom().shuffle(result)
    return "".join(result)

“每类至少一个”是方便用户通过网站规则校验的工程约束,它不会替代长度和字符空间带来的随机性。字符集越小,长度就越重要;为了避开少量符号而把密码缩短,往往得不偿失。

生成结果不会出现在调试日志里。界面刷新时也不把旧密码放进撤销栈,避免用户按快捷键后把敏感内容重新显示出来。

5. 核心实现二:可读口令与强度评估

有些账户必须在手机、电视或远程终端上手动输入,纯随机符号密码并不方便。这时可以使用多个随机词组成的口令:

def make_passphrase(words, count=5, separator="-"):
    if count < 3:
        raise ValueError("口令至少使用三个词")

    selected = [secrets.choice(words) for _ in range(count)]
    return separator.join(selected)

词表中的单词不需要秘密,但必须足够大、没有明显重复和规律。口令估算熵可以用近似公式:

import math

def estimate_entropy(alphabet_size, length):
    if alphabet_size <= 1 or length <= 0:
        return 0.0
    return length * math.log2(alphabet_size)

这个数字假设每个位置独立且均匀随机。实际密码如果被用户修改、重复使用或受到网站规则限制,安全性会下降。界面因此把它标为“理论估算”,不显示“绝对安全”之类的结论。

强度提示只根据当前生成规则显示:长度、字符空间、是否使用重复字符和估算熵。它不会把一个用户手动输入的密码上传分析,也不会因为分数高就推荐重复使用。

6. UI 定制:敏感内容不应该停留太久

界面分成两个模式:随机密码和可读口令。参数改变后只更新规则说明,用户点击“生成”时才产生新结果,避免每次拖动滑块都在屏幕上刷出大量密码。

生成结果默认使用等宽字体,并提供“显示/隐藏”切换。复制按钮旁边显示倒计时,例如“剪贴板将在 30 秒后清除”。清除操作会先确认剪贴板内容仍然是程序刚刚写入的那一段,避免把用户后来复制的新内容误删。

def clear_clipboard_if_unchanged(root, value):
    try:
        if root.clipboard_get() == value:
            root.clipboard_clear()
            root.update()
    except Exception:
        pass

退出程序时,界面会清空输入框和生成结果。配置文件只保存窗口大小、上次选择的字符类别等非敏感偏好;不会保存密码、口令、生成历史和剪贴板内容。

我还加了一个“暂停屏幕显示”的快捷键。临时离开座位前,可以把结果区域替换为遮罩;它不是安全边界,却能减少密码长时间暴露在屏幕上的机会。

7. 三个密码工具容易给人的错误安全感

坑一:长度和复杂度不能互相替代。 一个包含很多符号但只有八位的密码,未必比一组足够长的随机词组更好。工具同时展示长度和字符空间,不用单一颜色给出武断结论。

坑二:密码生成器不等于密码管理器。 生成后复制到聊天窗口、截图或明文笔记里,工具本身再安全也没有意义。程序会提示用户把重要凭据交给专门的密码管理器保存,但不会内置一个未经充分验证的存储箱。

坑三:排除易混字符会减少空间。 去掉 O/0、l/1 等字符可以改善手动输入,却会降低字符集大小。工具显示实际使用的字符空间,并建议用增加长度来补偿,而不是把“易读”标成“更安全”。

另外,网站的密码规则可能禁止某些符号或限制最大长度。生成器只能提供候选结果,最终仍要以目标服务的规则和账户安全策略为准。

8. 结尾:生成器只负责随机,保管仍然需要边界

做完这个工具后,我不再为每个新账户临时拼密码,也不会为了方便把同一个密码改几个数字继续使用。生成、复制、清除的过程变得很短,但责任边界反而更清楚:

  1. 随机性由系统安全随机源提供;
  2. 强度只做理论估算,不夸大结论;
  3. 重要凭据交给专门工具保管;
  4. 剪贴板和屏幕上的明文尽快清除;
  5. 不把生成历史和密码写进日志。

如果你也想写一个密码生成器,可以先从 secrets.choice、长度设置和剪贴板清除开始。不要急着加入云同步、账号体系和“自动判断是否安全”,因为这些功能会把一个本地小工具变成需要长期维护的安全产品。

生成密码并不难,难的是始终记得:随机只是第一步,保管、使用和不重复才决定最终风险。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。