OpenCode 实践课:4 分钟用 Python 写出一个命令行密码生成器

项目介绍

日常开发中经常需要生成随机密码——部署服务、创建测试账号、配置 API Key,每次都手打一串乱码太麻烦。今天我们用 OpenCode 写一个命令行密码生成器,支持自定义长度、字符类型、批量生成和密码强度评估。技术栈:Python 3 + argparse + secrets 模块,零外部依赖

最终效果:

$ python passgen.py -l 16 -n 3
dG7$kP2@vL9#mX1w  [强度: ★★★★☆]
aR3!nQ8&cV5%yB0p  [强度: ★★★★☆]
jF6^eU1*rT4$hN9s  [强度: ★★★★☆]

大约 100 行 Python,全程用自然语言指挥 OpenCode 完成。

准备工作

  • Python 3.8+
  • 安装了 OpenCode(npm install -g @anthropic/opencode 或参考 opencode.ai 文档)
  • 在项目目录下执行 opencode 启动交互会话

实践过程

第一步:生成一个简单的随机密码

先让 OpenCode 搭个骨架。

我对 OpenCode 说:

> 用 Python 写一个命令行密码生成器脚本 passgen.py,要求:
> 1. 默认生成 12 位密码,包含大小写字母、数字和特殊字符
> 2. 使用 secrets 模块保证密码学安全
> 3. 支持 -l 参数指定密码长度

OpenCode 响应:

OpenCode 先分析了需求,然后创建了 passgen.py,核心逻辑如下:

import secrets
import string
import argparse

def generate_password(length=12):
    alphabet = string.ascii_letters + string.digits + string.punctuation
    return ''.join(secrets.choice(alphabet) for _ in range(length))

def main():
    parser = argparse.ArgumentParser(description='安全密码生成器')
    parser.add_argument('-l', '--length', type=int, default=12, help='密码长度')
    args = parser.parse_args()
    print(generate_password(args.length))

关键要点: 指定了 secrets 模块而非 random——OpenCode 自动理解了"安全"这一约束。如果没提安全性,OpenCode 可能会用 random,那就不适合密码场景了。你的需求描述越精确,OpenCode 的产出越靠谱。

第二步:增加字符类型控制和批量生成

基础版跑通后,我让它加上两个常用功能。

我对 OpenCode 说:

> 帮我加两个功能:
> 1. 用 --no-upper、--no-lower、--no-digits、--no-symbols 控制排除哪些字符类型
> 2. 用 -n 参数支持一次生成多个密码,默认 1 个

OpenCode 响应:

OpenCode 修改了 argparse 部分和 generate_password 函数:

parser.add_argument('-n', '--count', type=int, default=1, help='生成数量')
parser.add_argument('--no-upper', action='store_true', help='不含大写字母')
parser.add_argument('--no-lower', action='store_true', help='不含小写字母')
parser.add_argument('--no-digits', action='store_true', help='不含数字')
parser.add_argument('--no-symbols', action='store_true', help='不含特殊字符')

然后按标志拼装字符集,循环输出。OpenCode 还主动加了防呆设计:如果四个排除项全选了,直接报错提示"至少保留一种字符类型"。

关键要点: 这里体现了 OpenCode 的"举一反三"能力——你只说了加排除选项,它自己想到了边界情况并做了防御。把边界情况交代清楚能省很多来回,但即使漏了,OpenCode 也经常能帮你补上。

第三步:加入密码强度评估

实用工具最好能告诉用户密码到底安不安全。

我对 OpenCode 说:

> 给生成的密码加上强度评估,用一个 5 星制显示。评估逻辑:
> - 基础分 = 字符集种类数(有大小写数字符号各 +1 分)
> - 长度≥12 加 1 分,≥16 加 1 分
> - 显示为类似 [强度: ★★★★☆] 的格式

OpenCode 响应:

OpenCode 在脚本里新增了一个 assess_strength 函数:

def assess_strength(password):
    score = 0
    checks = [
        (string.ascii_lowercase, 'lower'),
        (string.ascii_uppercase, 'upper'),
        (string.digits, 'digits'),
        (string.punctuation, 'symbols'),
    ]
    for charset, _ in checks:
        if any(c in charset for c in password):
            score += 1
    if len(password) >= 12:
        score += 1
    if len(password) >= 16:
        score += 1
    score = min(score, 5)
    return '★' * score + '☆' * (5 - score)

输出变成了 {密码} [强度: ★★★★☆]。OpenCode 还注意到星级最多 5 颗,用 min(score, 5) 做了上限。

关键要点: 当你描述评分规则时,尽量用"条件→结果"的方式写,这样 OpenCode 能直接把规则翻译成 if 语句,几乎零偏差。

第四步:完善帮助信息和收尾

最后让它整理一下 --help 输出,保证新用户一眼就知道怎么用。

我对 OpenCode 说:

> 把 argparse 的 description 和 epilog 补全,写上使用示例,让 --help 输出更友好。

OpenCode 补上了使用示例和描述文案,最终 --help 输出如下:

usage: passgen.py [-h] [-l LENGTH] [-n COUNT] [--no-upper] [--no-lower]
                  [--no-digits] [--no-symbols]

安全密码生成器 —— 基于 secrets 模块

options:
  -h, --help     显示此帮助信息
  -l, --length    密码长度(默认 12)
  -n, --count     生成数量(默认 1)
  --no-upper     不含大写字母
  --no-lower     不含小写字母
  --no-digits    不含数字
  --no-symbols   不含特殊字符

示例:
  passgen.py                    生成 1 个 12 位密码
  passgen.py -l 16 -n 5         生成 5 个 16 位密码
  passgen.py -l 8 --no-symbols  生成不含特殊字符的 8 位纯字母数字密码

完整代码

#!/usr/bin/env python3
import secrets
import string
import argparse


def assess_strength(password):
    score = 0
    checks = [
        (string.ascii_lowercase,),
        (string.ascii_uppercase,),
        (string.digits,),
        (string.punctuation,),
    ]
    for (charset,) in checks:
        if any(c in charset for c in password):
            score += 1
    if len(password) >= 12:
        score += 1
    if len(password) >= 16:
        score += 1
    score = min(score, 5)
    return '★' * score + '☆' * (5 - score)


def generate_password(length=12, no_upper=False, no_lower=False,
                      no_digits=False, no_symbols=False):
    charsets = []
    if not no_lower:
        charsets.append(string.ascii_lowercase)
    if not no_upper:
        charsets.append(string.ascii_uppercase)
    if not no_digits:
        charsets.append(string.digits)
    if not no_symbols:
        charsets.append(string.punctuation)

    if not charsets:
        raise ValueError('至少保留一种字符类型!')

    alphabet = ''.join(charsets)
    return ''.join(secrets.choice(alphabet) for _ in range(length))


def main():
    parser = argparse.ArgumentParser(
        description='安全密码生成器 —— 基于 secrets 模块,密码学安全随机',
        epilog='示例:\n'
               '  passgen.py                    生成 1 个 12 位密码\n'
               '  passgen.py -l 16 -n 5         生成 5 个 16 位密码\n'
               '  passgen.py -l 8 --no-symbols  不含特殊字符的 8 位密码',
        formatter_class=argparse.RawDescriptionHelpFormatter,
    )
    parser.add_argument('-l', '--length', type=int, default=12,
                        help='密码长度(默认 12)')
    parser.add_argument('-n', '--count', type=int, default=1,
                        help='生成数量(默认 1)')
    parser.add_argument('--no-upper', action='store_true',
                        help='不含大写字母')
    parser.add_argument('--no-lower', action='store_true',
                        help='不含小写字母')
    parser.add_argument('--no-digits', action='store_true',
                        help='不含数字')
    parser.add_argument('--no-symbols', action='store_true',
                        help='不含特殊字符')

    args = parser.parse_args()

    for _ in range(args.count):
        pwd = generate_password(
            length=args.length,
            no_upper=args.no_upper,
            no_lower=args.no_lower,
            no_digits=args.no_digits,
            no_symbols=args.no_symbols,
        )
        strength = assess_strength(pwd)
        print(f'{pwd}  [强度: {strength}]')


if __name__ == '__main__':
    main()

小结

整个项目从零到成品大约花了 4 分钟,共发了 4 条自然语言指令。对比传统开发方式:

| 环节 | 传统方式 | OpenCode |
|------|---------|----------|
| 查文档(secrets 模块用法) | 5-10 分钟 | 0(它自带知识) |
| 写 argparse 样板代码 | 3-5 分钟 | 10 秒 |
| 边界处理(空字符集报错) | 容易忘,回头补 | 自动补全 |
| 总计 | 约 20-30 分钟 | 约 4 分钟 |

OpenCode 最大的价值不在于"替你写代码",而在于消除上下文切换——你不用切到浏览器查文档、不用翻 Stack Overflow 找 argparse 语法、不用来回测试边界情况。你只需要描述"想要什么",它帮你把实现细节填上,你负责把关和微调。

如果想要更复杂的密码管理功能(比如加密存储、TOTP 支持),把需求细化后继续对话就行——OpenCode 会自动读取已有代码并在其基础上迭代,这正是 AI 编程助手的工作方式:渐进式构建,而不是一次性生成