我有这个脚本,它会生成随机密码,但需要对其进行洗牌。我找不到办法做到这一点。请帮我。
num=("0" "1" "2" "3" "4" "5" "7" "8" "9")
special=("@" "#" "$" "%" "*" "-" "+")
upper=(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)
lower=(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)
lower2=${#lower[*]} #${lower[$((RANDOM%lower2))]}
upper2=${#upper[*]} #${upper[$((RANDOM%upper2))]}
num2=${#num[*]} #${num[$((RANDOM%num2))]}
special2=${#special[*]} #${special[$((RANDOM%special2))]}
echo "${special[$((RANDOM%special2))]}${num[$((RANDOM%num2))]}${lower[$((RANDOM%lower2))]}${upper[$((RANDOM%upper2))]}${lower[$((RANDOM%lower2))]}${upper[$((RANDOM%upper2))]}${lower[$((RANDOM%lower2))]}${upper[$((RANDOM%upper2))]}"
这是输出:@7nOyIaJ
如何随机化它?
答案1
我假设你希望它是随机的,因为“特殊”总是第一位的。这是一个巨大的 hacky 方法。笔记:你的脚本是scr.bash
.
$ echo $(./scr.bash | fold -w1 | shuf | tr -d '\n')
例子
$ echo $(./scr.bash | fold -w1 | shuf | tr -d '\n')
qT*Jyv8Y
$ echo $(./scr.bash | fold -w1 | shuf | tr -d '\n')
QbOvX3n-
$ echo $(./scr.bash | fold -w1 | shuf | tr -d '\n')
*Q5nGgIt
这很粗糙,但向您展示了方法。
细节
该fold
命令会将输出分成每行 1 个字符。还有其他方法可以做到这一点,但我选择了fold
。该shuf
命令可以将行“打乱”成随机顺序。该命令将从我们所做的初始折叠中tr
删除换行符 ( )。\n
答案2
@slm 给出的答案很好地利用了 shell 中可用的工具,但与“scr.bash”结合使用时有点复杂。如果您有 Python(版本 2.7 或 3.x),这里有一个脚本可以更容易地完成相同的工作:
#!/usr/bin/env python
"""
Create a formulaic but reasonably strong password.
"""
import random
def shuffled_password():
"""Using one random member of special and num and three members each
from upper and lower return a shuffled string of their concatenation.
"""
num = list('012345789')
special = list('@#$%*-+')
upper = list('ABCDEFGHIJKLMNOPQRSTUVWXYZ')
lower = list('abcdefghijklmnopqrstuvwxyz')
random.shuffle(num)
random.shuffle(special)
random.shuffle(upper)
random.shuffle(lower)
letters = [special[0], num[0]]
letters.extend(lower[0:3] + upper[0:3])
random.shuffle(letters)
s = ''.join(letters) # funny way to turn list of chars into string
return s
if __name__ == '__main__':
print(shuffled_password())
我在探索您的方法的组合复杂性的过程中编写了这段代码。上面有人提到使用pwgen
;我一开始以为它一定比你自制的方法强,但我的猜测是错误的。
即使没有,你的方法也会shuffle(letters)
产生 210 亿个组合。这会产生一个估计熵39 位。这从强度测试中得到了非正式的评级:
36 - 59 位 = 合理;相当安全的网络密码和公司密码
添加最后的随机播放会向混合中添加大约 5 位熵。以供参考,
pwgen --symbols --numerals
生成估计熵为 37 位的密码。我将此归因于 pwgen 尝试生成“可记忆”的密码,从而以某种方式减少了输出集。根据强度测试的类别,这仍然是“合理的”。
注意:我的组合数学,特别是在多重排列中,是有限的,欢迎更正。
答案3
这纯 Bash解决方案也适用于多字节 UTF-8 字符,如果区域设置正确(例如LANG=C.UTF-8
)。
我们简单地使用字符串操作和一些bash 友好的算法,例如费舍尔-耶茨洗牌:
# shuffle() - shuffle a string
# $1: The string to shuffle
#
# The string is shuffled using the Fisher–Yates shuffle method :
# https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle
#
# @return: 0, output the shuffled string to stdout.
shuffle() {
local _str="$1" _res
local -i _i _cur
for (( _i = ${#_str} ; _i > 0; --_i )); do
_cur=$((SRANDOM % _i))
_res+=${_str:$_cur:1}
_str="${_str:0:_cur}${_str:_cur+1}"
done
printf "%s" "$_res"
}
结果 :
$ for i in {1..5}; do echo $(shuffle "@7nOyIaJ"); done
@IJn7Oay
Oa7Jn@yI
Oa@n7IJy
JaO7ny@I
OJI@n7ay
$ for i in {1..5}; do printf "%s\n" $(shuffle "abc山藤123Å"); done
2bca13藤Å山
Åc13藤a山2b
a2b山1c3Å藤
1a3b藤2cÅ山
山3Åc1a2藤b
答案4
我相信最简单的方法是(来源):
echo "