Bash on * 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
Damit dies korrekt funktioniert, $a
darf im Voraus kein gültiges, aber nicht zufälliges Kennwort festgelegt werden. Wenn Sie einschließen a=
und eine Zeile voranstellen möchten, sind das drei weitere Zeichen, aber Sie können das Ding wiederholt ausführen. Sie können natürlich auch alle Zeilenumbrüche durch neue ersetzen, ;
sodass Sie einen Einzeiler haben, den Sie so oft ausführen können, wie Sie möchten.
Darüber hinaus sollten Sie LC_ALL=C
( LANG
und LC_CTYPE
insbesondere) länderspezifische Umgebungsvariablen festgelegt oder nicht festgelegt haben , da die Zeichenbereiche davon abhängen, dass die Sortierreihenfolge der ASCII-Reihenfolge entspricht.
/dev/urandom
ist eine Quelle für zufällige Bytes. !-~
ist der Bereich aller zulässigen Zeichen, wie in der Frage angegeben. tr -dc
Entfernt alle Zeichen, die nicht im nächsten Argument aufgeführt sind. head
Nimmt 15 der verbleibenden Zeichen. grep
prüft, ob jede der erforderlichen Arten mindestens einmal vorkommt. Die Eingabe besteht aus vier Kopien des Kandidaten. Die Reihenfolge der Symbole spielt also keine Rolle. Daher haben alle möglichen Passwörter eine Chance, ausgewählt zu werden. Das -q
to grep unterdrückt die Ausgabe.
Aus unbekannten Gründen, /dev/random
anstatt /dev/urandom
ewig zu dauern. Es scheint, als wäre die Entropie ziemlich schnell erschöpft. Wenn Sie cd
Lust haben /dev
, können Sie weitere Bytes vermeiden, aber das fühlt sich ein bisschen wie Schummeln an.
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
Um den Code lesbar zu machen, habe ich nach der Schleife eine neue Zeile und einen Einzug eingefügt, die nicht erforderlich sind und die ich nicht gezählt habe.
Dies ist im Wesentlichen die gleiche Idee wie in der Bash-Version. Die zufällige Quelle ist hier random.sample
, die Elemente nicht wiederholt. Um diesem Umstand entgegenzuwirken, verwenden wir 15 Exemplare der Liste der zulässigen Buchstaben. Auf diese Weise kann jede Kombination auftreten, auch wenn solche mit wiederholten Buchstaben seltener vorkommen. Aber ich entscheide mich, dies als Feature und nicht als Bug zu betrachten, da die Frage nicht für alle Permutationen die gleiche Wahrscheinlichkeit erforderte, sondern nur die Möglichkeit.
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)
Eine neue Zeile und ein neuer Einzug werden nicht gezählt. Abgesehen von etwas Python-3-spezifischem Syntax-Overhead ist dies die gleiche Lösung wie für 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)
Ich habe die Zeilenumbrüche zur besseren Lesbarkeit hinzugefügt, aber nicht gezählt.
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
Zeilenumbruch und Einrückung in der Schleife hinzugefügt, aber nicht gezählt. Wenn Sie Lust dazu haben, können Sie dies wieder in eine einzelne ;
Zeile verschieben.