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
Per funzionare correttamente, $a
non deve essere impostato su una password valida ma non casuale in anticipo. Se vuoi includere a=
e una linea spezzata in avanti, ci sono altri tre personaggi ma ti consente di eseguire ripetutamente la cosa. Ovviamente puoi anche sostituire tutte le nuove linee in ;
modo da avere un solo liner che puoi eseguire tutte le volte che desideri.
Inoltre, è necessario impostare LC_ALL=C
o meno le variabili di ambiente specifiche della locale ( LANG
e LC_CTYPE
in particolare), poiché gli intervalli di caratteri dipendono dall'ordine di confronto che è uguale all'ordine ascii.
/dev/urandom
è la fonte di byte casuali. !-~
è l'intervallo di tutti i caratteri consentiti, come specificato nella domanda. tr -dc
rimuove tutti i caratteri non elencati nel prossimo argomento. head
prende 15 dei personaggi rimanenti. grep
controlla se ciascuno dei tipi richiesti si verifica almeno una volta. Il suo input consiste in quattro copie del candidato, quindi l'ordine dei simboli non ha importanza, quindi tutte le possibili password hanno la possibilità di essere selezionate. Il -q
grep sopprime l'output.
Per ragioni sconosciute, /dev/random
invece di /dev/urandom
richiedere secoli. Sembra che l'entropia si sia esaurita abbastanza rapidamente. Se cd
in /dev
, è possibile evitare alcuni più byte, ma che si sente un po 'come barare.
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
Per rendere leggibile il codice ho aggiunto una nuova riga e un rientro dopo il ciclo che non sono necessari e che non ho contato.
Questa è essenzialmente la stessa idea della versione bash. La fonte casuale qui è random.sample
, che non ripeterà gli elementi. Per contrastare questo fatto, utilizziamo 15 copie dell'elenco delle lettere consentite. In questo modo, ogni combinazione può ancora verificarsi, anche se quelli con lettere ripetute si verificano meno spesso. Ma decido di considerare questa una caratteristica, non un bug, poiché la domanda non ha richiesto la stessa probabilità per tutte le permutazioni, solo la possibilità.
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)
Una nuova riga e un rientro non vengono conteggiati. A parte alcuni overhead di sintassi specifici di Python-3, questa è la stessa soluzione di 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)
Ho aggiunto le nuove righe per la leggibilità, ma non le ho contate.
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
Interruzione di riga e rientro all'interno del loop aggiunti ma non conteggiati. Se ne hai voglia, puoi di nuovo spostarlo su una ;
riga separata.