跳到主要内容

password-generator-20261103

收藏0

本地离线随机密码生成器,按指定长度和字符集(大小写字母、数字、特殊符号)生成密码学安全的高强度随机密码,支持批量生成、排除易混淆字符、保证每类字符至少出现一次,全程不联网。

让 AI 安装

Mercury最新版本 0.1.0更新于 2026-11-03下载 0 次

scripts/New-Password.ps1

3.9 KB
1#requires -Version 5.1
2<#
3.SYNOPSIS
4 生成密码学安全的随机密码。
5.DESCRIPTION
6 使用 System.Security.Cryptography.RandomNumberGenerator 生成无偏随机密码,
7 支持自定义长度、字符集、批量生成、排除易混淆字符、保证每类字符至少一个、结果写文件。
8 全程离线,不发起任何网络请求。
9.PARAMETER Length
10 密码长度,默认 16,范围 4-128。
11.PARAMETER Count
12 生成密码条数,默认 1,范围 1-100。
13.PARAMETER ExcludeAmbiguous
14 排除易混淆字符:0 O o 1 l I | ` ' "。
15.PARAMETER NoLowercase
16 不使用小写字母。
17.PARAMETER NoUppercase
18 不使用大写字母。
19.PARAMETER NoDigits
20 不使用数字。
21.PARAMETER NoSymbols
22 不使用特殊符号。
23.PARAMETER OutFile
24 将结果写入指定文件(UTF-8 无 BOM);不指定则只输出到屏幕。
25.EXAMPLE
26 .\New-Password.ps1 -Length 20 -Count 3
27.EXAMPLE
28 .\New-Password.ps1 -NoSymbols -ExcludeAmbiguous
29#>
30[CmdletBinding()]
31param(
32 [ValidateRange(4, 128)]
33 [int]$Length = 16,
34
35 [ValidateRange(1, 100)]
36 [int]$Count = 1,
37
38 [switch]$ExcludeAmbiguous,
39 [switch]$NoLowercase,
40 [switch]$NoUppercase,
41 [switch]$NoDigits,
42 [switch]$NoSymbols,
43
44 [string]$OutFile
45)
46
47Set-StrictMode -Version 2.0
48
49# 组装字符集
50$sets = New-Object System.Collections.Generic.List[string]
51if (-not $NoLowercase) { $sets.Add('abcdefghijklmnopqrstuvwxyz') }
52if (-not $NoUppercase) { $sets.Add('ABCDEFGHIJKLMNOPQRSTUVWXYZ') }
53if (-not $NoDigits) { $sets.Add('0123456789') }
54if (-not $NoSymbols) { $sets.Add('!@#$%^&*()-_=+[]{};:,.?/') }
55
56if ($sets.Count -eq 0) {
57 throw '至少保留一个字符集,不能同时关闭全部四类字符。'
58}
59
60if ($ExcludeAmbiguous) {
61 $ambiguous = [char[]]@('0', 'O', 'o', '1', 'l', 'I', '|', [char]96, [char]39, [char]34)
62 for ($i = 0; $i -lt $sets.Count; $i++) {
63 $s = $sets[$i]
64 foreach ($c in $ambiguous) { $s = $s.Replace([string]$c, '') }
65 $sets[$i] = $s
66 }
67 $sets = [System.Collections.Generic.List[string]]@($sets | Where-Object { $_.Length -gt 0 })
68 if ($sets.Count -eq 0) {
69 throw '排除易混淆字符后没有可用字符,请调整参数。'
70 }
71}
72
73$allChars = -join $sets
74$rng = [System.Security.Cryptography.RandomNumberGenerator]::Create()
75$buffer = New-Object byte[] 1
76
77# 返回 [0, exclusiveMax) 内的无偏随机整数(拒绝采样,exclusiveMax 不超过 256)
78function Get-RandomIndex {
79 param([int]$ExclusiveMax)
80 $limit = 256 - (256 % $ExclusiveMax)
81 do {
82 $rng.GetBytes($buffer)
83 } while ($buffer[0] -ge $limit)
84 return [int]($buffer[0] % $ExclusiveMax)
85}
86
87function Get-RandomChar {
88 param([string]$CharSet)
89 return $CharSet[(Get-RandomIndex -ExclusiveMax $CharSet.Length)]
90}
91
92if ($Length -lt $sets.Count) {
93 Write-Warning "长度 $Length 小于启用的字符集数 $($sets.Count),无法保证每类字符至少出现一个。"
94}
95
96$results = New-Object System.Collections.Generic.List[string]
97
98for ($n = 0; $n -lt $Count; $n++) {
99 $chars = New-Object System.Collections.Generic.List[char]
100
101 # 每个启用字符集先各取一个,保证类别齐全
102 if ($Length -ge $sets.Count) {
103 foreach ($s in $sets) {
104 $chars.Add((Get-RandomChar -CharSet $s))
105 }
106 }
107
108 # 剩余位置从合并字符池随机取
109 while ($chars.Count -lt $Length) {
110 $chars.Add((Get-RandomChar -CharSet $allChars))
111 }
112
113 # Fisher-Yates 洗牌
114 for ($i = $chars.Count - 1; $i -gt 0; $i--) {
115 $j = Get-RandomIndex -ExclusiveMax ($i + 1)
116 $tmp = $chars[$i]
117 $chars[$i] = $chars[$j]
118 $chars[$j] = $tmp
119 }
120
121 $results.Add(-join $chars)
122}
123
124$rng.Dispose()
125
126if ($OutFile) {
127 [System.IO.File]::WriteAllLines($OutFile, $results, (New-Object System.Text.UTF8Encoding($false)))
128 Write-Output "已写入 $($results.Count) 个密码到:$OutFile"
129} else {
130 Write-Output $results
131}

文件内容是平台检查时读出的文本,只供查看。平台不会运行包里的任何脚本或程序。