在* nix上重击(109)
while ! grep -Pq [A-Z].*[a-z].*[0-9].*[\\W_]<<<$a$a$a$a
do a=`tr -dc !-~</dev/urandom|head -c15`
done
echo $a
要正常工作,$a
一定不要预先将其设置为有效但非随机的密码。如果您想在a=
前面加上一行,则可以再输入三个字符,但是它允许您重复运行该事物。很显然,您也可以将所有换行符替换为,;
因此您可以单行执行,只要您愿意就可以执行。
此外,你应该设置LC_ALL=C
或不设置任何特定的语言环境的环境变量(LANG
和LC_CTYPE
特别),因为字符的范围取决于排序顺序等于ASCII顺序。
/dev/urandom
是随机字节的来源。!-~
是问题中指定的所有允许字符的范围。tr -dc
删除所有未在其下一个参数中列出的字符。head
剩余15个字符。grep
检查每种必需种类是否确实至少发生一次。它的输入由候选者的四个副本组成,因此符号的顺序无关紧要,因此所有可能的密码都有可能被选择。该-q
到grep来禁止输出。
由于未知的原因,/dev/random
而不是/dev/urandom
费时。熵似乎很快就耗尽了。如果您cd
进入/dev
,则可以避免更多的字节,但这有点像作弊。
Python 2(138)
import re,random
a=''
while not re.search('[A-Z].*[a-z].*[0-9].*[\W_]',a*4):
a=''.join(random.sample(map(chr,range(33,127))*15,15))
print a
为了使代码易于阅读,我在循环后添加了换行符和缩进,这不是必需的,也不计在内。
这基本上与bash版本中的想法相同。此处的随机源为random.sample
,不会重复元素。为了解决这个问题,我们使用了15个允许的信件清单。这样,每种组合仍然可以发生,尽管带有重复字母的组合出现的频率会降低。但是我决定考虑将此功能作为功能,而不是错误,因为问题并不需要所有排列的均等概率,而仅是可能性。
Python 3(145)
import re,random
a=''
while not re.search('[A-Z].*[a-z].*[0-9].*[\W_]',a*4):
a=''.join(random.sample(list(map(chr,range(33,127)))*15,15))
print(a)
一个换行符和一个缩进再次不计算在内。除了某些Python-3特定的语法开销外,这与Python 2的解决方案相同。
的JavaScript(161)
a=[];for(i=33;i<127;)a.push(s=String.fromCharCode(i++));
while(!/[A-Z].*[a-z].*[0-9].*[\W_]/.test(s+s+s+s))
for(i=0,s="";i<15;++i)s+=a[Math.random()*94|0];alert(s)
我添加了换行符,以提高可读性,但不包括在内。
R(114)
s<-""
while(!grepl("[A-Z].*[a-z].*[0-9].*(\\W|_)",paste(rep(s,4),collapse="")))
s<-intToUtf8(sample(33:126,15,T))
s
循环内的换行和缩进已添加,但不计算在内。如果您愿意,可以再次将其移至单行;
。