文章目录
-
- Mac随机生成密码-小工具
-
- [1 openssl 生成密码](#1 openssl 生成密码)
-
- 举例说明生成长度
-
- [1-2 :2 字节是多少位?](#1-2 :2 字节是多少位?)
- [1-3 :16 位能分成几个 6 位?](#1-3 :16 位能分成几个 6 位?)
- [2 标准 Base64 字符表(RFC 4648 )](#2 标准 Base64 字符表(RFC 4648 ))
- [3 如何**精确控制最终密码长度**?](#3 如何精确控制最终密码长度?)
- [4 实用示例:生成 16 位强密码(不含特殊符号限制字符)](#4 实用示例:生成 16 位强密码(不含特殊符号限制字符))
- [5 写一个shell脚本](#5 写一个shell脚本)
-
- [5.1 写一个shell 脚本 `genpass.sh`](#5.1 写一个shell 脚本
genpass.sh) - [5.2 把这个脚本 放到 PATH 路径下面](#5.2 把这个脚本 放到 PATH 路径下面)
- [5-3 效果演示](#5-3 效果演示)
- [5.1 写一个shell 脚本 `genpass.sh`](#5.1 写一个shell 脚本
- [6 参考文档](#6 参考文档)
Mac随机生成密码-小工具
有时候 想生成随机密码,要么就是需要到一些网页上生成, 今天 我们来写一个shell 脚本 ,不需要什么特别的依赖 ,方便我们本地生成随机密码。
openssl 就提供了可以生成密码的功能
1 openssl 生成密码
bash
openssl rand -base64 32
命令逐部分解释
-
openssl这是 macOS(以及 Linux)系统自带的 OpenSSL 工具套件,用于加密、证书管理、随机数生成等。 -
rand这是 OpenSSL 的一个子命令,专门用于生成加密安全的随机字节。 -
-base64表示将生成的原始二进制随机数据编码为 Base64 字符串 ,这样输出就是可读的 ASCII 字符(如aB3$kL9...),便于复制使用。
如果不加
-base64,输出会是乱码(二进制),不适合当密码。
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 输出长度(含 =) |
|---|---|
| 12 | 16 |
| 15 | 20 |
| 18 | 24 |
| 24 | 32 |
| 32 | 44 (含 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 个字符)
| 索引 | 字符 | 索引 | 字符 | 索引 | 字符 | 索引 | 字符 |
|---|---|---|---|---|---|---|---|
| 0 | A | 16 | Q | 32 | g | 48 | w |
| 1 | B | 17 | R | 33 | h | 49 | x |
| 2 | C | 18 | S | 34 | i | 50 | y |
| 3 | D | 19 | T | 35 | j | 51 | z |
| 4 | E | 20 | U | 36 | k | 52 | 0 |
| 5 | F | 21 | V | 37 | l | 53 | 1 |
| 6 | G | 22 | W | 38 | m | 54 | 2 |
| 7 | H | 23 | X | 39 | n | 55 | 3 |
| 8 | I | 24 | Y | 40 | o | 56 | 4 |
| 9 | J | 25 | Z | 41 | p | 57 | 5 |
| 10 | K | 26 | a | 42 | q | 58 | 6 |
| 11 | L | 27 | b | 43 | r | 59 | 7 |
| 12 | M | 28 | c | 44 | s | 60 | 8 |
| 13 | N | 29 | d | 45 | t | 61 | 9 |
| 14 | O | 30 | e | 46 | u | 62 | + |
| 15 | P | 31 | f | 47 | v | 63 | / |
3 如何精确控制最终密码长度?
由于 Base64 长度由输入字节数决定,且带填充符,不能直接指定"我要 20 位"。但你可以通过以下方法间接控制:
方法一:生成后截取所需长度(推荐)
bash
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 位,反推字节数:
text
所需字节数 ≈ ceil(N * 3 / 4)
例如,想要 24 位密码:
- 24 × 3 / 4 = 18 → 用
openssl rand -base64 18 - 输出正好是 24 字符(无
=,因为 18 是 3 的倍数)
bash
openssl rand -base64 18
# 输出示例:aB3$kL9mN2pQ7rS5tU8vW1xY
✅ 这种方式无填充符,更干净。
4 实用示例:生成 16 位强密码(不含特殊符号限制字符)
bash
# 生成 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
bash
#!/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 路径下面
bash
# 复制脚本
cp genpass.sh /usr/local/bin/genpass.sh
# 添加权限
chmod +x /usr/local/bin/genpass.sh
5-3 效果演示
bash
(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 参考文档
https://datatracker.ietf.org/doc/html/rfc4648#section-4
分享快乐,留住感动. '2025-12-08 21:00:52' --frank