代码改变世界

Mac随机生成密码-小工具 - 教程

2026-01-12 18:16  tlnshuju  阅读(0)  评论(0)    收藏  举报

Mac随机生成密码-小工具

有时候 想生成随机密码,要么就是需要到一些网页上生成, 今天 我们来写一个shell 脚本 ,不需要什么特别的依赖 ,方便我们本地生成随机密码。

openssl 就提供了可以生成密码的功能

1 openssl 生成密码

openssl rand -base64 32

命令逐部分解释

  1. openssl 这是 macOS(以及 Linux)系统自带的 OpenSSL 工具套件,用于加密、证书管理、随机数生成等。

  2. rand 这是 OpenSSL 的一个子命令,专门用于生成加密安全的随机字节

  3. -base64 表示将生成的原始二进制随机数据编码为 Base64 字符串,这样输出就是可读的 ASCII 字符(如 aB3$kL9...),便于复制使用。

如果不加 -base64,输出会是乱码(二进制),不适合当密码。

  1. 32这是 要生成的随机字节数(bytes),不是最终密码的字符长度!

关键:Base64 编码后的实际长度

Base64 编码规则:

  • 3 个字节 → 编码为 4 个字符
  • 所以 n 字节 → 大约 ⌈n × 4/3⌉ 个字符
  • 并且 Base64 输出总是 4 的倍数,不足会补 = 填充符。
  • Base64 是把 每 6 位 当作一个字符
举例说明生成长度

32 字节 = 30 字节 + 2 字节

前 30 字节:没问题,10 组 × 3 字节 → 40 个 Base64 字符。

问题在最后 2 字节(也就是你疑惑的“余 2”部分):

1-2 :2 字节是多少位?
  • 2 × 8 = 16 位
1-3 :16 位能分成几个 6 位?
  • 16 ÷ 6 = 2 个完整的 6 位,还剩4 位
    • 第1个 6 位 → 字符1
    • 第2个 6 位 → 字符2
    • 剩下 4 位 → 不够 6 位,但我们可以在右边补 2 个 0,凑成第3个 6 位 → 字符3

✅ 所以 2 字节可以生成 3 个 Base64 字符

但注意:第3个字符是靠补 0 得到的,并不代表真实数据。解码时需要知道“最后这个字符只有前 4 位有效”。

Base64 协议规定:编码结果必须是 4 的倍数 (为了对齐和简化解码)。

因此:

输入字节数 (n)Base64 输出长度(含 =
1216
1520
1824
2432
3244(含 1~2 个 =

✅ 所以 openssl rand -base64 32 实际生成的是 44 位长的字符串(例如:WoHrnVBqejD27JsJolYqPdgC0BEwhzznfHD0PPevxeY=

注意:末尾可能有 =,某些系统或网站不允许密码包含 =,需手动删除或替换。

2 标准 Base64 字符表(RFC 4648 )

  • 大写字母 A–Z(26 个)
    A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
  • 小写字母 a–z(26 个)
    a b c d e f g h i j k l m n o p q r s t u v w x y z
  • 数字 0–9(10 个)
    0 1 2 3 4 5 6 7 8 9
  • 两个额外符号
    +/

这总共是:26 + 26 + 10 + 2 = 64 个字符

填充字符(Padding)

虽然不属于编码字符集本身,但在实际使用中,Base64 编码通常会在末尾使用 = 作为填充字符,以确保编码后的字符串长度是 4 的倍数。

  • = 不属于 64 个编码字符之一,仅用于对齐。

标准 Base64 字符表(共 64 个字符)

索引字符索引字符索引字符索引字符
0A16Q32g48w
1B17R33h49x
2C18S34i50y
3D19T35j51z
4E20U36k520
5F21V37l531
6G22W38m542
7H23X39n553
8I24Y40o564
9J25Z41p575
10K26a42q586
11L27b43r597
12M28c44s608
13N29d45t619
14O30e46u62+
15P31f47v63/

3 如何精确控制最终密码长度

由于 Base64 长度由输入字节数决定,且带填充符,不能直接指定“我要 20 位”。但你可以通过以下方法间接控制:


方法一:生成后截取所需长度(推荐)
openssl rand -base64 32 | tr -d '=+' | tr -d '\n' | cut -c1-20

解释:

  • tr -d '=+':删除 Base64 中的 =+(有些网站不接受)
  • tr -d '\n':去掉换行符
  • cut -c1-20:只取前 20 个字符

⚠️ 注意:删除字符会略微降低熵(安全性),但对 20+ 位密码影响极小,仍非常安全。


方法二:计算所需字节数(近似)

如果你希望 Base64 输出 大约 N 位,反推字节数:

所需字节数 ≈ ceil(N * 3 / 4)

例如,想要 24 位密码

  • 24 × 3 / 4 = 18 → 用 openssl rand -base64 18
  • 输出正好是 24 字符(无 =,因为 18 是 3 的倍数)
openssl rand -base64 18
# 输出示例:aB3$kL9mN2pQ7rS5tU8vW1xY

✅ 这种方式无填充符,更干净。


4 实用示例:生成 16 位强密码(不含特殊符号限制字符)

# 生成 16 字节 → Base64 输出 24 字符 → 截取前 16 位
openssl rand -base64 16 | tr -d '=+/' | cut -c1-16

说明:/ 有时也被某些系统视为路径分隔符而拒绝,所以一并删掉。


安全性说明

  • openssl rand 使用的是操作系统的加密安全随机数生成器(macOS 上是 /dev/random 或 CCRNG),足够安全用于密码生成。
  • date | md5$RANDOM 等伪随机方式强得多。

总结

目标命令
快速生成强密码(约 44 位)openssl rand -base64 32
生成 恰好 24 位(无 =openssl rand -base64 18
生成 自定义长度(如 20 位)`openssl rand -base64 32

5 写一个shell脚本

5.1 写一个shell 脚本 genpass.sh
#!/bin/bash
# date: 2025-12-04
# description: 生成一个随机密码,包含大小写字母、数字
# author: Frank
# usage: sh genpass.sh [长度]
gen_password() {
if [[ "$1" == "-h" || "$1" == "--help" ]]; then
echo "用法: bash $0 [长度]"
echo "生成指定长度的随机密码(默认16位),仅含字母和数字。"
echo "生成一个16位的随机密码"
echo "示例: bash $0 16 "
return 0
fi
# 默认长度为 16
local length=${1:-16}
if [[ ! "$length" =~ ^[0-9]+$ ]] || [ "$length" -le 0 ]; then
echo "❌ 请提供一个正整数作为密码长度!" >&2
return 1
fi
# 保证生成的密码足够随机且包含多种字符 +10 避免截断时长度不足,然后裁剪到指定长度
# 3个字节编码成4个字符,理论应该是 length * (3/4)  这里防止 特殊字符导致生成长度不够,故乘以3/2
openssl rand -base64 $((length * 3 / 2 + 10)) | tr -d '=+/ \n\r\t' | cut -c1-"$length"
}
gen_password "$@"

当然这个脚本中已经把一些特殊字符去掉了,如果有些需要特殊字符的情况,可以修改一下脚本,或者自己手动添加特殊字符 #@$ 等 一些特殊的字符

5.2 把这个脚本 放到 PATH 路径下面
# 复制脚本
cp genpass.sh  /usr/local/bin/genpass.sh
# 添加权限
chmod +x /usr/local/bin/genpass.sh
5-3 效果演示
(base)  ~/ which genpass.sh
/usr/local/bin/genpass.sh
(base)  ~/
(base)  ~/ genpass.sh -h
用法: bash /usr/local/bin/genpass.sh [长度]
生成指定长度的随机密码(默认16位),仅含字母和数字。
生成一个16位的随机密码
示例: bash /usr/local/bin/genpass.sh 16
(base)  ~/ genpass.sh
R5s4BjWOrNE2719y
(base)  ~/ genpass.sh
0pNZjbiK1WgfX8tH
(base)  ~/ genpass.sh  12
Eqwy8KEywotJ
(base)  ~/ genpass.sh  8
j5uO6c9W

6 参考文档

rfc4648 文档

https://datatracker.ietf.org/doc/html/rfc4648#section-4

分享快乐,留住感动. '2025-12-08 21:00:52' --frank