如何生成没有重复字符的随机字符串?

问题描述 投票:0回答:5

我正在尝试在 Bash 中生成一个符合 MacOS 密码要求的密码,其中之一是它不能包含重复的字符(aa、bb、44、00 等)。

我知道我可以使用

openssl rand -base64
/dev/urandom
并使用
tr -d
来操作输出字符串。我使用
grep -E '(.)\1{1,}'
搜索重复字符,但如果我使用此正则表达式删除 (
tr -d (.)\1{1,}'
),它会删除整个字符串。我什至尝试
tr -s '(.)\1{1,}'
将字符压缩到仅出现一次,但在某些尝试中它不断生成重复的字符。有可能实现我想要的目标吗?

P.S.:在这种情况下,我无法下载任何“密码生成器工具”,例如 pwgen 等。一定是“本土”

linux bash macos terminal tr
5个回答
1
投票

有具体尺寸要求吗?其他需要的字符吗?

怎么样-

    openssl rand -base64 20 | sed -E 's/(.)\1+/\1/g'

如果您有强制执行的最小密码长度范围 -

openssl rand -base64 $((13+RANDOM%10)) |  sed -En 'H; ${ x; s/\n//g; s/(.)\1+/\1/g; s/^(.{10,25}).*/\1/; p; }'

(更新添加输出长度护栏)


0
投票

抱歉,我无能为力,但我想帮助你。

如何迭代地获取唯一的字符,例如。通过

chars=$(openssl rand -base64)
pwd=

for (( i=0; i<${#chars}; i++ )); do
  if [[ "$(echo $pwd | grep "${chars:$i:1}")" == "" ]]; then
    pwd=$pwd${chars:$i:1}
  fi
done

0
投票

问题可能是您有不可打印的字符,因此它不会“实际上”重复。如果你第一次得到第一个,例如30 个字符,然后删除任何非字母数字、非标点符号字符,然后挤压任何这些字符,然后从剩下的内容中获取前 20 个字符,这似乎有效:

cat /dev/urandom | tr -dc '[:alnum:][:punct:]' | fold -w ${1:-30} | head -n 1 | tr -s '[:alnum:][:punct:]' | cut -c-20

输出例如:

]'Zc,fs6m;wUo%wLIG%K 2O3Ff4dzi30~L.RH8jR0 sU?,WkK]&I;z'|eTSLjY 5gK]\H51i@Rtux.{bdC= :g"\?5JsjBd1r])2^WR+ ;{cR:jY\rIc&Q(2yo:|- fFykmxvZ|ATX_l6L(8h: ^Sd*,V%9}bWnTYNv"w?' 6foMgbU6:n<*cWj2W=3& *v39FWmB@LwE5O`a3C36



0
投票

其中任何一个都会挤压重复:

tr -cs '\0' tr -s '[:graph:][:space:]'

它们的区别仅在于我们如何引用“所有字符”。第一个是“null 的补集”,第二个是所有可打印字符和所有空白字符。可能有一种更简洁的方法来指定“所有字符”。

或使用 sed:

sed -E 's/(.)\1+/\1/g'

这既挤压了可打印字符,又删除了空格:

tr -ds '[:space:]' '[:graph:]'

32 个非空白字符且无重复的示例:

tr -ds '[:space:]' '[:graph:]' < /dev/urandom | dd bs=32 count=1

此外,此示例指定允许的字符列表(字母、数字和 
_.

),然后压缩任何重复:

tr -dc '[:alnum:]_.' < /dev/urandom |
tr -sc '\0' |
dd bs=32 count=1

输出示例:

9mCEqrhHPwmq7.1qEky6qn4jqzDpRK7b

将 dd 放在末尾意味着我们在删除重复之后
得到 32 个字符。您可能还想添加

status=none 来隐藏 stderr 上的 dd 日志记录。


不清楚您是否不想重复连续字符或根本不希望重复字符(

0
投票
),但是这么说

#! /bin/bash awk -vN=20 ' { n=split($0,ch,""); for (i=1; i<n; i++) { a[ch[i]]++ } n=0; for (c in a) { if (++n > N) { break; } printf("%c",c) } printf("\n") } ' < <(openssl rand -base64 32)

这从 32 个随机字节中生成了
N
长度的密码,没有重复的字符(

即 N 应该远小于 32

© www.soinside.com 2019 - 2024. All rights reserved.