前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >用 shell 脚本批量生成强密码

用 shell 脚本批量生成强密码

作者头像
用户1148526
发布2024-08-08 08:23:46
800
发布2024-08-08 08:23:46
举报
文章被收录于专栏:Hadoop数据仓库

        Linux 上可以使用一行命令批量生成随机字符串:

代码语言:javascript
复制
cat /dev/urandom | LC_ALL=C tr -dc "[:graph:]" | fold -w 16 |head -100

        这个命令组合主要用于生成一个随机的、包含可打印字符(不包括空格)的字符串列表,每个字符串长度为16个字符,总共生成100个这样的字符串。下面是对命令各部分的详细解析:

  1. cat /dev/urandom:
    • cat 命令用于读取文件内容并将其输出到标准输出。
    • /dev/urandom 是一个特殊的设备文件,提供了无限长度的伪随机数据流。与 /dev/random 相比,/dev/urandom 不会因缺少熵(随机性)而阻塞输出,但它可能包含较少的随机性。
  2. | LC_ALL=C tr -dc "[:graph:]" |:
    • 管道符号 | 用于将前一个命令的输出作为后一个命令的输入。
    • LC_ALL=C 设置环境变量 LC_ALL 为 C,这通常用于确保命令的行为在不同的语言环境中保持一致。特别是,它影响字符分类(如哪些字符是“可打印的”)。
    • tr -dc "[:graph:]" 使用 tr(translate 或 delete/complement)命令。-d 选项删除(实际上是忽略)输入中不匹配给定集合的字符,-c 选项是取补集的意思,即删除集合外的所有字符。[:graph:] 是一个字符类,表示所有可打印字符(除了空格)。因此,这个命令的作用是从 /dev/urandom 的输出中筛选出所有可打印字符(不包括空格)。
  3. | fold -w 16 |:
    • 再次使用管道将前一个命令的输出作为输入。
    • fold -w 16 命令用于将输入文本折叠成每行宽度为16个字符的段落。在这个上下文中,它确保每个生成的随机字符串长度为16个字符。
  4. head -100:
    • 最后,head -100 命令从折叠后的输出中取出前100行。由于每行都是一个长度为16的随机字符串,因此最终结果是100个这样的字符串。

        综上所述,这个命令组合的作用是生成一个包含100个随机字符串的列表,每个字符串由16个随机选择的可打印字符(不包括空格)组成。这样的字符串可以用于各种需要随机标识符的场合,如密码生成、测试数据生成等。

但是,如果要求密码中必须包含数字、大小写字母、特殊字符,那么这条命令的结果并不是每次都符合要求。创建内容如下的脚本文件 GenerateStrongPassword.sh:

代码语言:javascript
复制
#!/bin/bash
if [ ! -n "$1" ] ;then
    echo "执行方式:GenerateStrongPassword.sh 密码个数"
    exit
fi

is_positive_integer() {
    # 正则表达式判断是否为正整数
    regex='^[0-9]+$'
    if [[ $1 =~ $regex ]] && [ "$1" -ge 0 ]; then
        return 0
    else
        return 1
    fi
}
 
# 调用函数检查参数是否为正整数
if !(is_positive_integer "$1") then
    echo "参数必须是正整数"
    exit
fi

num=1 
password=`cat /dev/urandom | LC_ALL=C tr -dc "[:graph:]" | fold -w 16 | head -$1`
regexp_str='^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[^a-zA-Z0-9]).{16}$'

for i in $password
do
    if grep -oP $regexp_str <<< $i; then
          :
    else
        echo "$i	$((num++))"
    fi
done

        执行脚本生成 100 个密码,结果如下:

代码语言:javascript
复制
[root@vvml-yz-hbase-test~]#./GenerateStrongPassword.sh 100
6t&)KjX&'v/]6OgF
@evZ^G{5,}&e,j\.
!X&VG.YYi6eXzuSj
P3q=P2u_%:G$"uY8
LiQ|`1iYF!,;:t%i
v(CiR[,]PNY}z<D5
2D=J0N,]fac_@Z\s
H!:k*Kvj+WbzqVng	1
*^(Lt+`vY0+#jpG,
w03dsuQx4dRK1-F4
dG^|Y[:Mp?L/(fG=	2
gZLm,:>=e&q4nrJe
9a+rx&e_TO;)BzW/
Q}yQY%gS-}T9T<<2
$sbs*i1q?tm`EcmE
ua!blnpcER"d7F[_
$K.z/MDf=<~J3V!F
Cs'pYR%|5%aXm4Ja
V)!x0qU.ORtB#vDH
OD5;^Sl@ruqZ9!(U
}P`X9\F^13YxR(hL
p@?>acOQ\~WY=E!$	3
bt7s[N?{E_!zy.L-
ZPwTb#]0j/VC%N4@
p3j+X86d|u>$#aTM
RjYUcJ8%{l4&>ST|
vA|=WgfljDhi?clg	4
COjkZYDww16r9CHS	5
YDhf:B%L+[7E|O]]
yj@p$O`M4$G6yvnQ
=_`p!MLXF7]nm>v'
@ao]vs\izFQ'D[+q	6
Ck!]IA'>o-$`2ye(
`^(V{iTRNzBB20\C
U]<ayX6J'}G(!Lkk
U=yx*rb4oWKa|o&x
zVH\Z5TG{2JH>Q1e
m1)&^}A_[@Z_=sA[
fH!(>SX"j#^54w+N
,5y@`q#+&B\duw$=
w}XS;RA.zvg$X961
Otv8#?mI^Q+P<k[p
!~~+5{~OV1$[=mY6
g|8*X+ej1kSTLSrp
T<vt%[P!>}cD(sG=	7
&lWpH~e.s'(A)xjd	8
DlSM>\h.vOVNR!uq	9
cUg0~u?WLzFl!}]'
*+mnW=XE<eexuxMt	10
324]zMD:0`cKH6_Q
d@)YW}%:et2{qWPr
IKil*my<MLkS6$H7
v0Qh|pSWDQUrhQ9H
M2g9aZCM?;<B68|*
6C?nD?[S(0S-r3o=
oML/&z41b3yTP$`5
bd4]b/{2eS(RTylU
<g24mIW;$uuIdz=/
G|ro,?JKHNBsvJqZ	11
P)lv[V{{<y91odt{
J[H3R)<x^u9]>nL$
W`f6yB|'WAlPpy&P
C>*yDPvN^uwr(Hun	12
Q!~GP|,PY`Cu1h!G
a(HA3.WTiHd|)Sw?
I-nrZn{Kuo<]Jqer	13
K~h5LlM.^/8``o6s
)^TUjQBb+P&ehF_T	14
P_3YF%'GcHM"4IG1
YDHSP?pL+x[t]w)e	15
}iiF6VL?aLPPipOf
){FOr03.O,2y4sRC
QN>#RF(VEZ9}e$Ki
/C#t^/v\XZ0~IiQ.
z7+7:*uivHuh+,%k
.Px~gxZ\UE|G"7*l
Os<fc.WZ=i*fTZe#	16
\%FFabpNq#WP#v6&
Y%p'y9N:M30Bh;G^
rlu=LeuKZ.9oyuRJ
~L"V33aBXF@76Gp6
=pKJ:tvg'|teoUJ9
>RL.))?\Rax@lTq#	17
lE+^s;NiS(z3|wIe
U,ss]R7`dJ<}w$YG
Mq'nMF6+Rn~UN:A.
7=AAZ6To=,=cQdD#
BhF}Adl/9qlNk=,a
*HvGQ$[Se]-)o(Sy	18
O9-4quTrWt@f)bSI
-Iz(W">_s+xjy<mY	19
,EU0YBHWE]^5xoG}
">W<j\y,Z,Ia_F9d
EnK{CP\A]8|ETY'0
k!WbYe~18qwr"s%M
PCb'/y\3Q?W>jSk@
Mx%D?2XcF5C$wGCx
Kl+~htGD&5Rp!O.s
qy5ZV("I7>*K2.Ux
qD<&h()(\%N[X1Z%
[root@vvml-yz-hbase-test~]#

        脚本中使用正则表达式对生成的密码进行判断。

  • 正则表达式说明:
    • ^ 代表开始。
    • (?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[^a-zA-Z0-9]) 用四个肯定顺序环视零宽断言对字符进行判定。
    • (?=.*[a-z]) 判断小写字母是否存在。
    • (?=.*[A-Z]) 判断大写字母是否存在。
    • (?=.*[0-9]) 判断数字是否存在。
    • (?=.*[^a-zA-Z0-9]) 判断特殊字符是否存在。
    • .{16} 代表任意 16 个字符。
    • $ 代表结尾。

        可以看到,有 19 个密码不满足要求,其中 18 个不包含数字,一个不包含特殊字符(第5个)。经过多次测试,约有 10% - 20% 会出现这种情况。下面修改脚本,批量生成强密码,具体需求如下:

  • 批量生成 100 个密码。
  • 密码长度统一为 16 个字符。
  • 密码中包含数字、大小写字母、特殊字符。

        主要做的修改是:当判断生成的密码不符合要求时重新生成一个,继续判断,直到满足要求为止。修改后的脚本内容如下:

代码语言:javascript
复制
#!/bin/bash
if [ ! -n "$1" ] ;then
    echo "执行方式:GenerateStrongPassword.sh 密码个数"
    exit
fi

is_positive_integer() {
    # 正则表达式判断是否为正整数
    regex='^[0-9]+$'
    if [[ $1 =~ $regex ]] && [ "$1" -ge 0 ]; then
        return 0
    else
        return 1
    fi
}
 
# 调用函数检查参数是否为正整数
if !(is_positive_integer "$1") then
    echo "参数必须是正整数"
    exit
fi

num=1 
password=`cat /dev/urandom | LC_ALL=C tr -dc "[:graph:]" | fold -w 16 | head -$1`
regexp_str='^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[^a-zA-Z0-9]).{16}$'

for i in $password
do
    if grep -oP $regexp_str <<< $i > /dev/null ; then
        echo "$i	强密码"
    else
        a=`cat /dev/urandom | LC_ALL=C tr -dc "[:graph:]" | fold -w 16 | head -1`
        until echo "$a" | grep -oP $regexp_str > /dev/null
        do
            a=`cat /dev/urandom | LC_ALL=C tr -dc "[:graph:]" | fold -w 16 | head -1`
        done
        echo "$a	重新生成的强密码    $((num++))"
    fi
done

        执行脚本结果如下:

代码语言:javascript
复制
[root@vvml-yz-hbase-test~]#./GenerateStrongPassword.sh 100
)qW.(|`mzr'/1wk*	强密码
h7lT$4B\DnYV=_/q	强密码
K5GiC8fZl.,QLfus	强密码
rQ7B6%ldF}aoS+{Q	重新生成的强密码    1
-t6{IFi6/6YmXzV%	重新生成的强密码    2
iOt?ywH/y5}**/3E	强密码
|<t*VF(0zh~H;jr1	强密码
f0]1)2]>^|t<Z1;:	强密码
W[Z?)7$Ip=|O2GH=	强密码
)cs,6Em3L,R]Mu7?	强密码
Wb1_Vw`^3${EmUQ"	强密码
:g4)/%/,"N0=WEn*	强密码
+0^6Z*,{gX[NF'"'	强密码
]aY/F/"5biKU'=S:	强密码
$Kb.=yJvgcb/a2,-	强密码
2WtnW1Drfp**.iMT	强密码
@60Y'Z]4ZVFPVKDf	强密码
/{S--By-D{`h5\p~	强密码
Jg<>5pyww:eg}Z"&	重新生成的强密码    3
cLV]/}T8g#|PuyE^	强密码
,<Nf:1eU>i$Swug#	强密码
&XVMc^|el86XB8:M	强密码
d=X?[W(+M)e0lQ&6	强密码
Z,{:@32uPe,]8S:*	重新生成的强密码    4
m\/A]qIG{/\9[gHm	强密码
kv~}t8-Y4s+0u[CA	强密码
c1z#V_buM6{/.8r5	强密码
(u)3?S"V'Ng8MW#v	强密码
9}:g3?(Y0=ivOAV0	强密码
rbGS_]7Lb-P|P]e]	重新生成的强密码    5
.&$d&#@:EnNPb*|8	强密码
gQfUazBph|xHJ0%&	强密码
ek`*Oz'HNS_8ro}!	强密码
V\{@%}6\]0eXU=*s	强密码
<6[lc:&j+")D('xJ	强密码
a4)Py>L.`4b(xX/Q	强密码
x^C4eaYDa^o-^~n-	强密码
4zG+}!eDsq%nrvo%	强密码
{wS?ItnVQ7YI|]H"	强密码
="Hq\M|6c(im4/H-	强密码
v6p+O^NVem~Q~^5l	重新生成的强密码    6
2^Q.i3$brBFcR79x	强密码
INQpz`t+;EiR7.\.	强密码
Q^4^x$ll(h!*!OjH	强密码
bUPN%Jx1m<dMnGN)	强密码
I0dEQi_jFS+/]|8"	强密码
B5!^i>0X2zI$kWg4	强密码
dRqpS[ow6>W@e.F)	强密码
")~#1#hr<:hp.W>c	强密码
jDFQ{D)$hDxr3W-9	强密码
ed]@SPda`Q0J@Ynx	重新生成的强密码    7
p/GONw@PD7$O]Z^-	重新生成的强密码    8
sUbyi<U)dq|?t~?4	强密码
CqU!8#I86i6gT+yO	强密码
@~p=h5UkbKDv^:s8	强密码
(Q3UeMpVXD!PR2,s	重新生成的强密码    9
7|R,gHV3A?xAtl0_	强密码
D.w7hL*6_^|C~;$\	强密码
31KT%|?tW\CLB/$l	强密码
l[X(t4hzS![Kk9yM	强密码
~~Q-mrw#\;mTeU0e	强密码
{NAb=M"b#3_-]xbL	强密码
]+'d*$}?f7tyE"Y5	强密码
.50+9_iC``\@P&H3	强密码
yiwK*!5m0;!ii#R[	强密码
ht@_<mYRSb7;Cb3u	强密码
GMos-d/9fVdl{sUS	强密码
9o<tr^jhgd|J9FER	强密码
,~V&A-er|7L8)bcY	强密码
_b(l5Bnv^c|8RC'*	强密码
x4.-&Y,^T(<)1P!D	强密码
Q#zC4\/Tc')E`@Yb	强密码
V<qf*Xbrhl&Hw1TV	强密码
p55p\=N3S!,oae5A	重新生成的强密码    10
~%z*T~K&mg1$OmEG	强密码
Y\e~BY?2T?BFH5j%	强密码
!:-Q%-']T/$8Fax0	强密码
YDSdM1LHy4.&//K_	强密码
4V.Fl\?>w46G;oCs	强密码
(E/eMO\ZB+9wCy[t	强密码
U8myJslO.;:4vVvg	强密码
*8bdJ19pUh&8=C=I	强密码
>[18S|~gO\d\Sx4M	强密码
$yOX6vW;[xONUtgL	强密码
WMrO/I@15t1TPc~D	强密码
,|z.uoN(l+#b2\9w	强密码
Rt8;JCv_T6G,;[$9	强密码
=[!`OBMW*$71L\vo	强密码
~,C_K$'-R6%v"%S(	强密码
ku4u>2P0Dj"XAjEo	强密码
6`/rR3O`'0jgv^eF	重新生成的强密码    11
~l`O72Pa/k=}sXck	强密码
3Jd4)`Q9X3:.$yl[	强密码
?}!jt%*1lKjVL9}v	重新生成的强密码    12
^c5QF;Z4`C#,4hxV	重新生成的强密码    13
4)(x~"F4?"NMNGma	强密码
3qrje;f2D.*wii2P	强密码
k`_)tAI_/,#9(%J1	强密码
b](\6)1z.G=RYfvu	重新生成的强密码    14
}5M%n}a;Dq'|R+]#	强密码
[root@vvml-yz-hbase-test~]#

        可以看到,所有 100 个密码都为强密码,完全满足需求。因为不满足需求的情况不到 20%,所以不用担心循环陷入无休止的迭代中。当然必须指出,这版实现使用的是“判错重来”方式,会有不到 20% 的密码生成是做了无用功。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-08-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档