使用“$RANDOM”在Bash中生成随机字符串

cnh2zyt3  于 2022-11-02  发布在  Linux
关注(0)|答案(9)|浏览(203)

我尝试使用Bash变量$RANDOM创建一个随机字符串,该字符串由一个包含整数和字母数字的变量中的8个字符组成,例如var="abcd1234ABCD"
我怎么能那样做呢?

vh0rcniy

vh0rcniy1#

使用参数扩展。${#chars}是可能的字符数,%是模运算符。${chars:offset:length}选择offset位置的字符,即在本例中为0长度($chars)。

chars=abcd1234ABCD
for i in {1..8} ; do
    echo -n "${chars:RANDOM%${#chars}:1}"
done
echo
ivqmmu1c

ivqmmu1c2#

对于那些在bash中寻找随机字母数字字符串的用户:
LC_ALL=C tr -dc A-Za-z0-9 </dev/urandom | head -c 64
与文档化功能相同:

function rand-str {
    # Return random alpha-numeric string of given LENGTH
    #
    # Usage: VALUE=$(rand-str $LENGTH)
    #    or: VALUE=$(rand-str)

    local DEFAULT_LENGTH=64
    local LENGTH=${1:-$DEFAULT_LENGTH}

    LC_ALL=C tr -dc A-Za-z0-9 </dev/urandom | head -c $LENGTH
    # LC_ALL=C: required for Mac OS X - https://unix.stackexchange.com/a/363194/403075
    # -dc: delete complementary set == delete all except given set
}
yshpjwxd

yshpjwxd3#

另一种生成32字节(例如)十六进制字符串的方法:

xxd -l 32 -c 32 -p < /dev/random

如果要使用大写字符,请添加-u

ngynwnxp

ngynwnxp4#

OPTION 1-无特定长度,不需要openssl,只有字母和数字,比 option 2

sed "s/[^a-zA-Z0-9]//g" <<< $(cat /dev/urandom | tr -dc 'a-zA-Z0-9!@#$%*()-+' | fold -w 32 | head -n 1)

演示:x=100; while [ $x -gt 0 ]; do sed "s/[^a-zA-Z0-9]//g" <<< $(cat /dev/urandom | tr -dc 'a-zA-Z0-9!@#$%*()-+' | fold -w 32 | head -n 1) <<< $(openssl rand -base64 17); x=$(($x-1)); done
示例:

j0PYAlRI1r8zIoOSyBhh9MTtrhcI6d
nrCaiO35BWWQvHE66PjMLGVJPkZ6GBK
0WUHqiXgxLq0V0mBw2d7uafhZt2s
c1KyNeznHltcRrudYpLtDZIc1
edIUBRfttFHVM6Ru7h73StzDnG

OPTION 2-无特定长度,openssl*需要 *,仅字母和数字,比 option 1

openssl rand -base64 12 # only returns

rand=$(openssl rand -base64 12) # only saves to var

sed "s/[^a-zA-Z0-9]//g" <<< $(openssl rand -base64 17) # leave only letters and numbers

# The last command can go to a var too.

演示:x=100; while [ $x -gt 0 ]; do sed "s/[^a-zA-Z0-9]//g" <<< $(openssl rand -base64 17); x=$(($x-1)); done
示例:

9FbVwZZRQeZSARCH
9f8869EVaUS2jA7Y
V5TJ541atfSQQwNI
V7tgXaVzmBhciXxS

不一定相关的其他选项:

uuidgencat /proc/sys/kernel/random/uuid
在未来100年内每秒产生10亿个UUID后,仅产生一个副本的概率约为50%。如果地球上每个人都拥有6亿个UUID source,则产生一个副本的概率约为50😇

6mzjoqzu

6mzjoqzu5#

没有使用$RANDOM,但值得一提。
使用shuf作为熵的来源(也称为随机性)(反过来,它可以使用/dev/random作为熵的来源,如'shuf -i1-10 --random-source=/dev/urandom)似乎是一个使用更少资源的解决方案:

$ shuf -er -n8  {A..Z} {a..z} {0..9} | paste -sd ""
tf8ZDZ4U
oymdgrw7

oymdgrw76#

head -1 <(fold -w 20  <(tr -dc 'a-zA-Z0-9' < /dev/urandom))

如果您打开了安全选项,则可以在bash脚本中安全地使用此选项:

set -eou pipefail

这是使用管道时bash退出状态141的解决方法

tr -dc 'a-zA-Z0-9' < /dev/urandom | fold -w 20 | head -1
hgb9j2n6

hgb9j2n67#

使用 sparse 数组来重排字符。


# !/bin/bash

array=()
for i in {a..z} {A..Z} {0..9}; do
    array[$RANDOM]=$i
done
printf %s ${array[@]::8} $'\n'

(Or大量随机字符串)


# !/bin/bash

b=()
while ((${#b[@]} <= 32768)); do
    a=(); for i in {a..z} {A..Z} {0..9}; do a[$RANDOM]=$i; done; b+=(${a[@]})
done
tr -d  ' ' <<< ${b[@]} | fold -w 8 | head -n 4096
q9yhzks0

q9yhzks08#

有点晦涩,但简短的解决方案是

RANDSTR=$(mktemp XXXXX) && rm "$RANDSTR"

希望您具有对当前目录的写访问权限;- )mktemp是核心实用程序的一部分
UPDATE:正如Bazi在注解中指出的,可以在不创建文件的情况下使用mktemp;- ),因此命令可以更短。

RANDSTR=$(mktemp --dry-run XXXXX)
8oomwypt

8oomwypt9#

基于Radu Gabriel's answer并使用GNU bash版本4.4.20和set -euxo pipefail进行测试的简化安全管道解决方法:

head -c 20 <(tr -dc [:alnum:] < /dev/urandom)

相关问题