Generador de contraseñas aleatorias

40

El servidor de dominio requiere que todos los empleados tengan una contraseña segura y aleatoria que cumpla con las siguientes reglas:

  • Exactamente 15 caracteres de largo.
  • Solo caracteres que se pueden escribir en el teclado (como se muestra a continuación en el tipo de código). No se permite enseñar a las ventas a usar códigos ALT + NUMPAD.
  • Al menos 1 letra minúscula: abcdefghijklmnopqrstuvwxyz
  • Al menos 1 letra mayúscula: ABCDEFGHIJKLMNOPQRSTUVWXYZ
  • Al menos 1 dígito numérico: 0123456789
  • Al menos 1 símbolo: `~!@#$%^&*()_+-={}|[]\:";'<>?,./

Para este propósito, TI ha encargado y distribuirá un generador de contraseñas aleatorias a todos los empleados. Todos los empleados deberán utilizar el generador de contraseñas aleatorias. Los requisitos para el generador de contraseñas aleatorias son, además de las restricciones de contraseña anteriores:

  • Debe poder generar todas las permutaciones de todos los caracteres permitidos.
  • Debe mostrar la contraseña generada en la pantalla.
  • Se requiere que el código sea lo más pequeño posible (en bytes).

Envíe su solución propuesta dentro de la próxima semana.

Hand-E-Food
fuente
10
También debe exigir que todas las contraseñas permitidas aparezcan con la misma probabilidad (de lo contrario, simplemente puedo hacer una lista de 30 caracteres con caracteres permitidos, barajarla y dar las primeras 15)
Martin Thoma
@moose, de acuerdo. He agregado una nueva regla.
Hand-E-Food
22
Los chicos de TI deberían ser despedidos, o al menos mejor educados: si genera contraseñas al azar, entonces restringir el conjunto de contraseñas permitidas a aquellas que incluyen al menos un carácter de cada categoría, de hecho, debilita las contraseñas, ya que reduce el tamaño de las contraseñas. El conjunto permitido. Y nuestros programas serían mucho más fáciles si no tuviéramos que verificar eso ... OK, no modifiquen el concurso después de que hayan llegado tantas presentaciones; Está bien como un desafío.
MvG
10
@MvG De hecho:correcthorsebatterystaple
Jonathon Reinhart
1
Realmente no ha respondido a @moose al exigir que todas las contraseñas sean generables. Deben aparecer con la misma probabilidad.
Ethan Bolker

Respuestas:

29

Mathematica (18)

Déjame un poco de trampa

= 15char ASCII pwd
&(^F7yP8k:*1P<t

PD no seguridad :)

ybeltukov
fuente
66
¿Dónde está el código?
DavidC
11
¿Se garantiza que satisfaga al menos uno de los requisitos de cada clase de personaje ?
Hand-E-Food
3
@ Hand-E-Food Sí, lo es! Si observa la interpretación, verá: longitud de contraseña 15, se requieren letras minúsculas, se requieren letras mayúsculas, se requieren números, se requieren caracteres especiales.
ybeltukov
66
+1 Inteligente, pero astuto.
DavidC
10
Sabía que Mathematica tiene una función para todo, pero ¿ esto ?
Konrad Borowski
13

Ruby, 74 69 bytes

Simplemente muestree aleatoriamente del rango ASCII 33 - 126 hasta que estén presentes todas las clases de caracteres:

$_=[*?!..?~].sample(15)*''until~/\d/&&~/[a-z]/&&~/[A-Z]/&&~/\W|_/
p$_

Ruby, 39 bytes

Usando el descubrimiento inteligente de los alces:

p"0123abcdABCD-+/<".chars.sample(15)*''

Editar para satisfacer a la mafia:

Tenga en cuenta que las reglas cambiaron después de que publiqué esto por primera vez. En ese momento, las dos entradas anteriores se aplicaban a las reglas. También me gustaría señalar que las reglas aún no están muy bien definidas:

(..) todas las permutaciones de todos los caracteres permitidos

"Permutaciones". No hay permutaciones de los caracteres permitidos que cumplan con el resto de las reglas, porque cualquier permutación del conjunto de caracteres permitidos es tan larga como el conjunto de caracteres permitidos (mientras que la contraseña debe tener 15 caracteres). Y no hay repeticiones en una permutación. Sin embargo, mi primera entrada es aún más "aleatoria" que muchas de las otras respuestas bien votadas aquí.

Sin embargo, aquí lo tienes. Permite repeticiones de caracteres y guiones bajos:

Ruby, 77 bytes

$_=([*?!..?~]*15).sample(15)*''until~/\d/&&~/[a-z]/&&~/[A-Z]/&&~/\W|_/
puts$_

También utilicé en putslugar de pen este porque pimprime la cadena entre comillas y algunos caracteres escaparon con una barra diagonal inversa.

Ruby, 70 bytes

Como señala Ventero, ~se puede omitir frente a las expresiones regulares y se printpuede reemplazar puts$_. Pero con la salida fea, esto también puede imprimir todas las contraseñas rechazadas, apretándolas en una sola línea:

puts$_=([*?!..?~]*15).sample(15)*''until/\d/&&/[a-z]/&&/[A-Z]/&&/\W|_/

Explicación

De acuerdo a lo pedido. $_es una variable semi-mágico que contiene la última línea de leer de la entrada - por lo que no siempre es necesario almacenarlo, como este . Sin embargo, aquí lo usamos debido a otra propiedad, a saber, que el ~operador le aplica una expresión regular directamente, un truco que aprendí por primera vez por cron . Reemplacé el uso de all, pero debería ser bastante fácil de entender si obtienes el resto ( ver los documentos ).

daniero
fuente
2
¿Podría explicar un poco su código? ¿Qué .all?{|r|~r}hacer? ¿Qué $_=hacer?
Martin Thoma
3
La línea de muestra es inteligente y todo, pero creo que viola "Debe ser capaz de generar todas las permutaciones de todos los caracteres permitidos". En ninguna parte dice que la contraseña solo puede contener anuncios en lo que respecta a las letras. Si z es un carácter permitido, debería haber una posibilidad> 0 de que z esté en la contraseña.
nitro2k01
1
¿ \WEn Ruby incluye el guión bajo _? En la mayoría de los dialectos regex sé que no. Y si su código no pudiera generar contraseñas donde un solo _era el único símbolo no alfanumérico, violaría un requisito. El segundo enfoque viola muy obviamente ese requisito, pero supongo que no estaba redactado correctamente en ese momento.
MvG
1
@ MVG: Tienes razón. \Wno contiene un guión bajo en RegEx ( fuente ) compatible con Perl .
Martin Thoma
1
Además, su solución se ve afectada por el mismo problema @moose y que tuve con Python: sampleno repite elementos, por lo que su código no puede generar contraseñas con elementos repetidos. ¿Puede solucionar estos dos problemas para que su respuesta se ajuste a la pregunta? Al ver cómo la suya es la solución líder, a excepción de Wolfram Alpha, sería bueno ver si puede conformarse y seguir manteniendo el liderazgo. Supongo que no debería ser demasiado difícil.
MvG
12

Java 8 - 354 329 319 275 267 caracteres

Solo por diversión, usando lambdas con Java 8: cada salida posible tiene la misma probabilidad de ser encontrada.

Utiliza el hecho de que los caracteres permitidos tienen códigos ascii consecutivos, de 33 a 126.

class A {
    //flags for, respectively, small caps, large caps, digits, punctuation
    static int a, A, d, p;

    public static void main(String[] x) {
        String s;
        do {
            //Using special String constructor that takes an int[]
            s = new String(new java.util.Random().ints(15, 33, 127)
                                .toArray(),
                           0, 15);
            a = A = d = p = 0;
            s.chars()
                .map(c ->
                      c > 96 & c < 123 ? a = 1
                    : c > 64 & c < 90  ? A = 1
                    : c > 47 & c < 58  ? d = 1
                    : (p = 1))
                .min();
        } while (a + A + d + p < 4);
        System.out.println(s);
    }
}

Salida de muestra:

.*;Tm?svthiEK`3  
o.dzMgtW5|Q?ATo  
FUmVsu<4JF4eB]1

Programa comprimido:

class A{static int a,A,d,p;public static void main(String[]x){String s;do{s=new String(new java.util.Random().ints(15,33,127).toArray(),0,15);a=A=d=p=0;s.chars().map(c->c>96&c<123?a=1:c>64&c<90?A=1:c>47&c<58?d=1:(p=1)).min();}while(a+A+d+p<4);System.out.println(s);}}

asilias
fuente
¿Qué tal while(a+A+d+p<4)junto con en a|=1lugar de a++? O máscaras de bits uso, es decir cosas como a|=1a través de a|=8, con a<15como condición de bucle. Esto ahorra otros 13 caracteres si conté correctamente.
MvG
Buen punto de @MvG: hice algo similar, ahorrando un par de caracteres adicionales, creo.
Assylias
@MvG ¡Y el uso new String(int[],int,int)guarda otros 40 caracteres impares!
Assylias
8

Python 2.X + 3.X (229 caracteres): generar y reemplazar

Idea

  1. Primero haga una lista con 15 símbolos permitidos
  2. Reemplazar una posición aleatoria rpor un dígito aleatorio
  3. Reemplace una posición aleatoria s, con s != r, por una letra mayúscula
  4. Lo mismo para la letra minúscula y el símbolo que en 2 y 3.

Código

from random import randint as r, shuffle as s
a=list(range(15))
p=a[:]
for i in range(15):
    a[i]=chr(r(32,126))
s(p)
a[p.pop()]=chr(r(48,57))
a[p.pop()]=chr(r(65,90))
a[p.pop()]=chr(r(97,122))
a[p.pop()]=chr(r(33,47))
print(a)

Python 2.X + 3.X (194 caracteres): generar y verificar

import random
from re import search as s
p=''
while not all([s("\d",p),s("[a-z]",p),s("[A-Z]",p),s("[\W_]",p)]):
 p=str(map(chr,[random.choice(list(range(33,127))) for i in range(15)]))
print(p)
  • Gracias a MvG que me dijo eso \uy \lno existe en Python regex.
  • Gracias a grc que me dijo que eso no random.sampletiene reemplazo, para obtener todas las contraseñas permitidas posibles necesitamos muestreo con reemplazo.

Usando falla en la descripción del problema

Actualmente, la descripción del problema no exige que cada símbolo / dígito aparezca con la misma probabilidad. Con la siguiente solución, no puede asumir nada sobre un solo símbolo y / o posición. Pero puedes hacerlo con múltiples.

Python 2.X + 3.X (62 caracteres)

from random import sample
print(sample("0123abcdABCD-+/<",15))

Gracias a daniero por la idea de usar muestra.

Martin Thoma
fuente
Muy suave encontrar el defecto! He conectado ese, pero puntos de bonificación por identificarlo. :-)
Hand-E-Food
Su gen & check es similar a mi enfoque. Por curiosidad: ¿dónde está documentado esto \ly demás para las expresiones regulares de Python? No lo veo en la referencia . Mi Python 3.3.3 ni siquiera acepta "\u". El str(…)no une las letras en 3.3.3 o 2.7.6. Una sugerencia para optmization: all(s("\\"+i,p)for i in "dluW").
MvG
random.sampleelige elementos sin reemplazo, por lo que no todas las contraseñas son posibles.
grc
@ MVG: Gracias. Acabo de ver eso \uy \les solo vim.
Martin Thoma
7

Bash en * 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

Para que funcione correctamente, $ano se debe establecer una contraseña válida pero no aleatoria por adelantado. Si desea incluir a=una línea en el frente, son tres caracteres más, pero le permite ejecutar la cosa repetidamente. Obviamente, también puede reemplazar todas las líneas nuevas por ;lo que tiene una línea que puede ejecutar con la frecuencia que desee.

Además, debería haber establecido LC_ALL=Co no establecer variables de entorno específicas de la localidad ( LANGy LC_CTYPEen particular), ya que los rangos de caracteres dependen de que el orden de clasificación sea igual al orden ASCII.

/dev/urandomes la fuente de bytes aleatorios. !-~es el rango de todos los caracteres permitidos, como se especifica en la pregunta. tr -dcelimina todos los caracteres que no figuran en su siguiente argumento. headtoma 15 de los personajes restantes. grepcomprueba si cada uno de los tipos requeridos ocurre al menos una vez. Su entrada consiste en cuatro copias del candidato, por lo que el orden de los símbolos no importa, por lo tanto, todas las contraseñas posibles tienen la posibilidad de ser seleccionadas. El -qto grep suprime la salida.

Por razones desconocidas, en /dev/randomlugar de /dev/urandomlleva años. Parece que la entropía se agotó bastante rápido. Si cden /dev, puede evitar algunos más bytes, pero que se siente un poco como hacer trampa.

Pitón 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

Para que el código sea legible, agregué una nueva línea y una sangría después del ciclo que no es necesario y que no conté.

Esta es esencialmente la misma idea que en la versión bash. La fuente aleatoria aquí es random.sample, que no repetirá elementos. Para contrarrestar este hecho, utilizamos 15 copias de la lista de letras permitidas. De esa manera, toda combinación puede ocurrir, aunque las que tienen letras repetidas ocurrirán con menos frecuencia. Pero decido considerar esto como una característica, no como un error, ya que la pregunta no requería la misma probabilidad para todas las permutaciones, solo la posibilidad.

Pitón 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 nueva línea y una sangría nuevamente no cuentan. Además de algunos gastos generales de sintaxis específicos de Python-3, esta es la misma solución que para 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)

Agregué las nuevas líneas para facilitar la lectura, pero no las conté.

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

Salto de línea y sangría dentro del bucle agregado pero no contado. Si lo desea, puede moverlo nuevamente a una sola ;línea separada.

MvG
fuente
¡Decir ah! Estaba a punto de señalar que podría haber usado greplen su código R. Si solo hubiera pensado en repetir la contraseña de prueba cuatro veces para poder hacer todas las comprobaciones en una. Y sabes, si solo hubiera pensado en sampley intToUtf8. Sin embargo, debe agregar replace=TRUE(o de manera más concisa, solo necesita agregar ,T) a su método de muestra para asegurarse de obtener todas las contraseñas posibles.
AmeliaBR
@AmeliaBR: Tienes razón, solucionó ese replace=Terror, gracias por señalarlo. Encontrar intToUtf8adivinando nombres probables con la finalización de tabulación me llevó bastante tiempo; Sabía que tal función tiene que existir, pero los nombres más comunes como chry así sucesivamente no se usaron.
MvG
@ MVG: No entiendo por qué su código Python termina en absoluto. ¿Por qué necesitas eso *4? Pensé que su expresión regular coincidiría con cualquier cadena, ese anuncio primero una letra mayúscula, luego cualquier cosa, luego una letra minúscula, que cualquier cosa ... ¿qué me equivoqué?
Martin Thoma
@moose: Como ya lo notó, mi expresión regular verifica las categorías requeridas en un orden específico. Pero al tomar la concatenación de cuatro copias del candidato actual, puedo asegurarme de que el orden ya no importa: incluso si mi contraseña son símbolos seguidos de dígitos seguidos de minúsculas seguidas de mayúsculas, entonces todavía habría una coincidencia. La única forma en que un partido puede fallar es si falta una categoría por completo. También tenga en cuenta que yo re.searchno re.match, así, el texto podría coincidir en cualquier lugar de la contraseña candidato. ¿Esto explica por qué terminará eventualmente?
MvG
Ah, no me di cuenta de que usas en re.searchlugar de re.match. Eso lo explica. Pero sigo pensando que no necesitas el *4. Gracias por la explicación (+1)
Martin Thoma
7

C # ( 123 - 139 103 - 127 caracteres compactados):

Usando un método de marco perfectamente adecuado en System.Web.dll:

class P
{
    static void Main()
    {
        Console.WriteLine(System.Web.Security.Membership.GeneratePassword(15, 1));
    }
}

Comprimido:

class P{static void Main()
{Console.WriteLine(System.Web.Security.Membership.GeneratePassword(15,1));}}

Ejemplo:

b+m2ae0K:{dz7:A

Alternativamente, tome el valor del segundo parámetro ( int numberOfNonAlphanumericCharacters) de la línea de comando:

class P
{
    static void Main(string[] a)
    {
        Console.WriteLine(System.Web.Security.Membership.GeneratePassword(15, int.Parse(a[0])));
    }
}
Rik
fuente
3
GeneratePasswordno admite el conjunto completo de símbolos especificado en la pregunta. Tampoco encontré ninguna garantía sobre el número mínimo de ocurrencias de cada categoría de personaje.
MvG
2
Puede compactar aún más usando class Py string[] a.
d3dave
@ MVG, eso es interesante. Parece que excluye cualquier símbolo que se use comúnmente para escribir caracteres acentuados en idiomas como el francés. Probablemente un movimiento inteligente. Cambiar el idioma del teclado sería suficiente para rellenar su contraseña.
Hand-E-Food
5

R (301 322 caracteres)

La corrección olvidó verificar los dígitos.

a='abcdefghijklmnopqrstuvwxyz';
f=as.factor(strsplit(paste(a,toupper(a),
    sep="0123456789`~!@#$%^&*()_+-={}|[]\\:\";'<>?,./"),"")[[1]]);
g=gsub("(.):","\\1",levels(q:q:q:q:q:q:q:q:q:q:q:q:q:q:q));
repeat{p=g[runif(1)*length(g)]; 
    if(grepl("[A-Z]",p)&&grepl("[a-z]",p)&&grepl("[0-9]",p)&&grepl("[^A-Za-z0-9]",p))break;};
print(p);

(espacio en blanco agregado solo para mayor claridad).

Genera todas las permutaciones posibles de 15 caracteres de los 94 caracteres. Luego, selecciona uno al azar hasta que coincida con los criterios.

La magia está en la q:qoperación, que genera un nuevo tipo de datos de factor que es la interacción de todos los factores en la primera qlista con todos los factores en la segunda lista , con cada combinación posible de esas dos listas incluidas en la lista de " niveles "de ese factor. Interactúa 15 copias de la lista de personajes permitidos y obtienes (94 ^ 15) niveles posibles.

Por favor, no intente esto en casa. El código tarda un par de segundos en descubrir todas las permutaciones de tres caracteres, realmente no puedo imaginar cuánto tiempo tomaría averiguar todas las permutaciones de 15 caracteres, si su computadora no se quedara sin memoria en el mientras tanto. Cuando ejecuté el script terminado (contraseña de tres caracteres) para verificarlo, la primera contraseña que escuchó fue "oO =", que creo que resume la reacción que debería tener ante este código.

AmeliaBR
fuente
@MvG tiene un script R que es mucho más práctico y mucho más corto, aunque mucho menos impresionante: codegolf.stackexchange.com/a/17700/12413
AmeliaBR
Sin embargo, me gusta tu idea. Muchos fragmentos de código de golf que vi permitieron que características específicas del lenguaje hicieran el trabajo duro. Y su código ciertamente lo hace para R, con esas interacciones.
MvG
4

Mathematica 170

r=RandomSample;f[i_]:=(FromCharacterCode/@Range@@i);
{t,A,a,n}=f/@{{33,126},{65,90},{97,122},{48,57}};
s=Complement[t,A,a,n];
""<>r[Join[RandomChoice/@{A,a,n,s},r[t,11]],15]

Ejemplos

"<]} Pg3 / e? 3 + Z ~ Oz"
"X / 8jWe @ f (_x5P: ="
"2wz2VQhtJC? * R7 ^"

DavidC
fuente
4

Python 2.7 (182)

import random as r,string as s
z=r.sample
j=list(z(s.ascii_lowercase,12)+z(s.ascii_uppercase,1)+z(s.digits,1)+z('`~!@#$%^&*()_+-={}|[]\\:";\'<>?,./',1))
r.shuffle(j)
print ''.join(j)
Jonathon Reinhart
fuente
Puede obtener 9 dígitos menos eliminando la unión, ya que no es requerido por el descriptivo del problema. Otros 2 menos eliminando espacios.
Martin Thoma
@moose Saqué los espacios justo antes de que comentaras :-) Siento que el jointipo tiene que estar allí: ¿Se espera que los usuarios entiendan la sintaxis de la lista de Python de la salida ['q', 'u', ...]:?
Jonathon Reinhart
1
Pensé en eliminar la impresión en absoluto. Cuando el tamaño en bytes es importante, pueden vivir en el tiempo de la tarjeta perforada. De esa manera, podrían leer la memoria ... con solo mirarla. O son "programadores reales": xkcd.com/378
Martin Thoma
1
Si estoy leyendo el código correctamente, esto no cumple con el requisito de todas las permutaciones , siempre tendrá 12 caracteres en minúscula, haciendo que las contraseñas con más de uno de los otros grupos (como aA$bc1111111111) sean imposibles.
IQAndreas
1
En defensa de Johnathon, creo que la regla de permutaciones se agregó 5 minutos después de su publicación.
Hand-E-Food
4

Golfscript (60)

Desde el obl. falta golfscript y como novato necesito la práctica de todos modos :)

[48 10{rand}:r~+65 26r+97 26r+33 15r+11,{;32 96r+}%~]{r}$''+

Simplemente construye una matriz con los 4 caracteres aleatorios requeridos + 11 y los ordena en orden aleatorio.

Joachim Isaksson
fuente
+1 para {r}$. Esa es una manera bastante sucia de barajar una lista, ¡me gusta! ;-)
Ilmari Karonen
... sin embargo, no creo que esto pueda salir, por ejemplo 0Aa~~~~~~~~~~~~. :-(
Ilmari Karonen
3

JavaScript 258 240 233 225

R=Math.random;a=b=>b[b.length*R()|0];for(x=[a(l="abcdefghijklmnopqrstuvwxyz"),a(u=l.toUpperCase()),a(n="0123456789"),a(s="`~!@#$%^&*()_+-={}|[]\\:\";'<>?,./")];15>x.length;x.push(a(l+u+n+s)));alert(x.sort(y=>.5-R()).join(""))

Usando una regla donde:

function(x){return x*x}puede reescribirse como function(x)x*x. Solo parece funcionar para funciones que devuelven un valor.

Próxima iteración, reducida x.sort(function().5-R())ax.sort(y=>.5-R())

Próxima iteración, reducida aún más con la notación de flecha gruesa, que lamentablemente solo funciona para Firefox 22 y superior.

WallyWest
fuente
Agradable compactación! : D
IQAndreas
2

JavaScript (269 caracteres compactados)

Para mayor claridad, este es el código antes de compactarlo con JS-Fiddle :

var lowerLetters = "abcdefghijklmnopqrstuvwxyz";
var upperLetters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
var numbers = "0123456789";
var symbols = "`~!@#$%^&*()_+-={}|[]\\:\";'<>?,./";
var allCharacters = lowerLetters + upperLetters + numbers + symbols;

String.prototype.randomChar = function() {
    return this[Math.floor(this.length * Math.random())];
}

var minLength = 15;
var result = [];

// Start off by picking one random character from each group
result.push(lowerLetters.randomChar());
result.push(upperLetters.randomChar());
result.push(numbers.randomChar());
result.push(symbols.randomChar());
// Next, pick a random character from all groups until the desired length is met
while(result.length < minLength) {
    result.push(allCharacters.randomChar());
}
result.shuffle(); // Finally, shuffle the items (custom function; doesn't actually exist in JavaScript, but is very easy to add) -> http://stackoverflow.com/questions/2450954/how-to-randomize-shuffle-a-javascript-array
result.join("");

Aquí se compacta a 269 caracteres ( JS-Fiddle ):

l="abcdefghijklmnopqrstuvwxyz";
u=l.toUpperCase();
n="0123456789";
s="`~!@#$%^&*()_+-={}|[]\\:\";'<>?,./";
R=Math.random;

function r(t){
    return t[~~(t.length*R())]
}

for(x=[r(l),r(u),r(n),r(s)];x.length<15;x.push(r(l+u+n+s)));
x.sort(function(){return .5-R()});
alert(x.join(""));
IQAndreas
fuente
Como estoy terminando líneas con punto y coma, se ignoraron todos los espacios en blanco extraíbles para el recuento de caracteres, pero se dejaron en claro.
IQAndreas
¿Qué quieres decir con shuffle()ser una "función personalizada"? ¿Es parte de JavaScript o código que tendría que escribir usted mismo?
Hand-E-Food
@ Hand-E-Food Quise decir que no está integrado en JavaScript, y dado que cualquier desarrollador aquí debería saber cómo mezclar una matriz, sentí que era innecesaria incluir la función en el código. Sin embargo, está disponible en el JS-Fiddle (línea 16).
IQAndreas
1
Mi punto es que cuenta para tu conteo de bytes. Pero ahora veo que lo has implementado en la versión compactada, así que ignórame. :-)
Hand-E-Food
2

Clojure (63):

(->> (map char (range 33 127)) (shuffle) (take 15) (apply str))

Pero debe mejorarse para garantizar que contenga al menos 1 carácter de cada categoría (Superior, Inferior, Dígito, Símbolo).

ntalbs
fuente
2

En sql-server

declare @a nvarchar(28)
set @a='abcdefghijklmnopqrstuvwxyz'
declare @b nvarchar(max)
set @b='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
declare @c nvarchar(max)
set @c='0123456789'
declare @d nvarchar(max)
set @d='~!@#$%^&*()_+-={}|[]\:";<>?,./'

select left(substring(@a,cast(rand()*10 as int),3)+substring(@b,cast(rand()*10 as int),6)+substring(@c,cast(rand()*10 as int),3)+substring(@d,cast(rand()*10 as int),5),15)

Véalo en acción - 1

verlo en acción - 2

vhadalgi
fuente
1
Tengo problemas para seguir la última línea, pero el código no parece cumplir con todos los requisitos de permutaciones .
IQAndreas
Su código nunca generará ninguna contraseña que comience ~0Aa, ni ninguna contraseña donde bsea ​​seguida a.
Heinzi
@Heinzi: sí, estoy de acuerdo con todas las permutaciones requeridas r no se tienen en cuenta, solo muestra una longitud de 15 caracteres elegidos al azar de a ... z, A..Z, 0..9,! ... + :(. ..
vhadalgi
2

SAS (191)

%macro c(p);compress(p,,"&p")ne''%mend;data x;length p$15;do x=1by 1;do t=1to 15;substr(p,t,1)=byte(ranuni(7)*94+33);end;if %c(kd)and %c(kl)and %c(ku)and %c(ad)then do;put p;stop;end;end;run;

*TQP,(f=h10*)S=

Comentado / sangrado:

%macro c(p); /*compress removes or keeps certain classes of characters*/
  compress(p,,"&p")ne''
%mend;
data x;
length p$15;
do x=1by 1;
    do t=1to 15;
        substr(p,t,1)=byte(ranuni(7)*94+33); /*give it a 33-126, byte discards the noninteger portion rounding down*/
    end;
    if %c(kd)and %c(kl)and %c(ku)and %c(ad)then do; /*k=keep d=digit l/u=lower/upper ad=remove digits and alphas*/
        put p;
        stop;  /*met our requirement, head home*/
    end;
end;
run;
Joe
fuente
2

PowerShell: 119

Código Gofled

for(;!($x-cmatch'.*(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[!-/:-@[-`{-~]).*')){$x='';1..15|%{$x+=[char](33..126|random)}}$x

Sin golf y comentado

# Start for loop definition.
for(
    # Skip variable initialization, start definition of run condition.
    ;
    # Loop runs if $x does not meet complexity requirements.
    # Length requirement is not tested here because it is enforced by the generator later.
    # Much thanks to @VasiliSyrakis for the RegEx help.
    !($x-cmatch'.*(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[!-/:-@[-`{-~]).*')
)
{
    # Reset $x in case the script block has already run.
    $x='';
    # Use ForEach-Object, via the % alias, to run a loop 15 times.
    1..15|%{
        # Append a random ASCII character from 33-126 to $x.
        # Note: Use get-random instead of random for faster performance.
        $x+=[char](33..126|random)
    }
}
# Display $x.
$x
# Variable cleanup - not included in golfed code.
rv x
Iszi
fuente
Creo que esta expresión regular puede hacerla un poco más corta: ^.*(?=.{15,})(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[!#$%&? "]).*$puede hacer una coincidencia con esto, que solo coincidirá cuando haya un Símbolo superior, inferior, de dígitos.
Vasili Syrakis
@VasiliSyrakis Ok, es posible que tengas que guiarme un poco por eso. Siéntase libre de iniciar una sala de chat si cree que tomará un tiempo. Un par de cosas en las que estoy confundido: 1.) Veo el número 15 incluido allí. ¿Es para asegurarse de que la cadena tiene exactamente 15 caracteres? Si es así, esto puede omitirse, ya que el script naturalmente solo genera cadenas de 15 caracteres. 2.) ¿Qué quieres decir con "solo coincidirá cuando hay un símbolo superior, inferior, de dígitos"? ¿Eso significa que solo coincidirá cuando haya exactamente uno de cada uno, o al menos uno de cada uno? El primero romperá las cosas.
Iszi
Además, ¿su RegEx ignora el orden de los caracteres? Por ejemplo, si sintonizado para concordar con cuerdas de 4 caracteres, que tanto 1aZ%y (p3Rcoincidir? Tuve algunas dificultades para encontrar formas de hacerlo en línea.
Iszi
Probé el nuevo RegEx contra la salida de mi script actual. No parece del todo confiable. Código: $x-cmatch'^.*(?=.{15,})(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[!#$%&? "]).*$'coincidencias buenas: C>suD1?hTwbDx(z j%4O]HyeG|u[U$5 O/rGeD0$hJk=GO/coincidencias 3evthX3_X^nBrR` fallidas : .nA ~ uYzrR4YV-r.`u-IjZE48ntQ;HxV
Iszi
¿Cómo abro una sala de chat?
Vasili Syrakis
1

Python 2.7 (149)

from random import*
''.join(map(lambda x:chr(randint(*(x[1]or(32,126)))),sorted(map(None,sample(range(15),15),((48,57),(65,90),(97,122),(33,47))))))

Escrito de una manera más legible (y no ejecutable);

from random import *
''.join(                                          # Concatenate characters to string
  map(                                            # Map all characters using below lambda
    lambda x:chr(randint(*(x[1] or (32, 126)))),  # Map a single range to a random character
                                                  # within a specific range if supplied,
                                                  # otherwise the default "all" range.
    sorted(                                       # After distributing ranges, sort
      map(None,                                   # zip_longest alternative, distributes the
                                                  # required ranges over 4 random positions
        sample(range(15), 15),                    # 0-14 in random order
        ((48, 57), (65, 90), (97, 122), (33, 47)) # The 4 required ranges
      )
    )
  )
)

Bastante sencillo y sorprendentemente no mucho más largo que una versión de "generar, reintentar en falla de partido".

Joachim Isaksson
fuente
¿Estás seguro de que esto realmente puede generar todas las contraseñas elegibles, por ejemplo, por ejemplo 0Aa~~~~~~~~~~~~? (Tenga en cuenta que '~' == chr(126))
Ilmari Karonen
1

PSQL (189)

Parece que PSQL es un poco detallado ... :)

SELECT ARRAY_TO_STRING(ARRAY_AGG(CHR((TRUNC((b-a)*RANDOM()+a))::int)ORDER BY RANDOM()),'')FROM(SELECT 32 a,127 b FROM generate_series(1,11)UNION ALL VALUES(48,58),(65,91),(97,123),(33,48))a

Demostración de SQLfiddle .

Joachim Isaksson
fuente
1

PHP, 235 225

Este script baraja los caracteres y luego se verifica a través de RegEx para asegurarse de que la contraseña sea segura (o se regenere).

<?php
while(!preg_match('/^(?=.*[A-Z])(?=.*[^A-Za-z])(?=.*[0-9])(?=.*[a-z]).{15}$/',$p)){ $p = substr(str_shuffle('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789`~!@#$%^&*()_+-={}|[]\:";\'<>?,./'),0,15); }
echo $p;
ub3rst4r
fuente
1
Inteligente, pero no permite caracteres duplicados.
Hand-E-Food
1
En lugar de while(true) ... if (condition) breakque pueda usarwhile (!condition)
exussum
1

Javascript (209)

r=Math.random;function t(x,y){return String.fromCharCode(Math.floor(y*r()+x))};x=[t(33,14),t(48,10),t(65,26),t(97,26)];for(i=0;i<11;i++)x.push(t(32,95));console.log(x.sort(function(){return r()-0.5}).join(''))

Semi-no-golfista;

// Return a character in the range [x,x+y)
function t(x,y) { return String.fromCharCode(Math.floor(y*Math.random()+x)) }
// Prefill required ranges
x=[ t(33,14), t(48,10), t(65,26), t(97,26)]
// Push 11 totally random (valid) characters
for(i=0; i<11; i++)
  x.push(t(32,95))
// Shuffle and output as string
console.log(x.sort(function(){return Math.random()-0.5})
             .join(''))
Joachim Isaksson
fuente
1

Perl, 92

No es tan conciso como la respuesta de Ruby, pero estoy seguro de que un asistente de Perl podría hacer esto aún más corto ... No estoy muy contento con todos los m//mensajes al final, pero parece funcionar y debería satisfacer las condiciones para eventualmente generar Todas las permutaciones.

do{$_=join"",map{(map{chr}33..127)[rand 94]}0..14}while!(/[A-Z]/&/[a-z]/&/\d/&/[\W_]/);print

Uso de la muestra:

perl -e 'do{$_=join"",map{(map{chr}33..127)[rand 94]}0..14}while!(/[A-Z]/&/[a-z]/&/\d/&/[\W_]/);print'

Editado para la validación fijar y cambiar [[:punct:]]a [\W_]después MVGS comentarios.

Dom Hastings
fuente
1
Su parte de generación es buena, pero su criterio de selección en la condición de bucle es simplemente incorrecto: por ejemplo, una contraseña de aaaaaaaaaaaaaaprovocaría que el bucle finalice. Debe probar los criterios con contraseñas no aleatorias para asegurarse de que hagan lo que usted quiere que hagan.
MvG
De hecho, estás en lo correcto, lo he arreglado y guardado algunos bytes ¡Gracias!
Dom Hastings
1
¿Estás seguro de esto [[:punct:]]? Supongo que preferiría el , which is shorter and of which I'm even more sure that it is correct, at least combined with your rango '[\ W_] 33..127`.
MvG
Un buen punto, creo que me preocupaba que \Wno incluyera _, sin embargo, tiene toda la razón, no es necesario: gist.github.com/anonymous/8301237 . ¡Gracias!
Dom Hastings
1

Java 7 ( 270 234 caracteres)

La premisa es la misma utilizada por @assylias con java 8 (generar contraseñas aleatorias hasta una contraseña válida). Sin embargo, en lugar de usar lambdas, la contraseña se genera iterando una matriz de caracteres y validada haciendo coincidir una expresión regular.

class A {
  public static void main(String [] a) {
    byte[] b = new byte[15];
    String s;
    do {
      new java.util.Random().nextBytes(b);
      s = new String(b);
    } while(!s.matches("(?=.*?[a-z])(?=.*?[A-Z])(?=.*?\\d)(?=.*?[!-/:-@\\[-`]).*"));
    System.out.println(s);
  }
}

Código Minificado:

class A {public static void main(String[] a){byte[] b=new byte[15];String s;do{new java.util.Random().nextBytes(b);s=new String(b);}while(!s.matches("(?=.*?[a-z])(?=.*?[A-Z])(?=.*?\\d)(?=.*?[!-/:-@\\[-`]).*"));System.out.println(s);}}
madoke
fuente
1

Potencia Shell


Versión One Liner (143 bytes)

sal g random;1..11|%{$P+=[char](33..126|g)};(65..90|g),(97..122|g),(48..57|g),(33..47+58..64+123..126|g)|%{$P=$P.insert((1..11|g),[char]$_)};$P

Mini versión (146 bytes)

sal g random
1..11|%{$P+=[char](33..126|g)}
(65..90|g),(97..122|g),(48..57|g),(33..47+58..64+123..126|g)|%{$P=$P.insert((1..11|g),[char]$_)}
$P

Versión legible (860 bytes)

function pwgen {

    # Fulfill Upper,Lower,Digit,Symbol requirement by predefining ASCII ranges for each
    # These will be added into the string beginning at line 24

    [array[]]$symbolrange = (33..47),(58..64),(123..126)

    [char]$upper = (get-random (65..90))
    [char]$lower = (get-random (97..122))
    [char]$digit = (get-random (48..57))
    [char]$symbol = $symbolrange | get-random

    [char[]]$requirement = $upper + $lower + $digit + $symbol

    # Create the first 11 characters using any ASCII character between 32 - 126

    foreach ($number in (1..11)) {
        [string]$pass += [char](get-random (33..126))
    }

    # Insert each requirement character at a random position in the string

    foreach ($char in $requirement) {
        [string]$pass = $pass.insert((Get-Random (1..11)),$char)
    }

    return $pass
}

Gracias a Iszi por varios consejos para acortar el código.

Vasili Syrakis
fuente
1
Esto no cubre todas las permutaciones. Como ejemplo, abcd1234ABCD{|}~nunca aparecerá porque $symbolobliga a que al menos uno de los símbolos esté entre ASCII 33 y 47.
Hand-E-Food
Dangit! ¿Debes señalar mi pereza? Es broma ... lo he editado ahora. También hice que cada carácter de "requisito" vaya a un índice separado dentro de la cadena, en lugar de agrupar los cuatro juntos en el mismo índice. Ahora, si pudiera acortar esto ...
Vasili Syrakis
¿Hay alguna razón por la que no puedas afeitarte un par de personajes más acortando $SR, tal vez $Q?
Iszi
También debe ser capaz de cosas como el corte (g(65..90))hacia abajo para 65..90|g'. And change the declaraciones foreach` a foreach-objectbucles utilizando el %alias. Ejemplo: foreach($N in (1..11)){... }debe ser factible como 1..11|%{... }. Estoy bastante seguro de que hay otras optimizaciones que son posibles, pero en realidad tengo una implementación completamente diferente en mente que estoy planeando probar más tarde.
Iszi
Buenos consejos :) Lo acorté a 213 bytes si saco los retornos de carro y los reemplazo con punto y coma.
Vasili Syrakis
1

Factor, 196 caracteres

Mismo algoritmo que MvG y alces. No es el más corto, pero debe satisfacer todos los criterios (actuales) en la pregunta:

USING: io kernel math pcre random sequences sequences.repeating ;
[ 15 94 random-integers [ 33 + ] "" map-as dup 60 cycle
"[A-Z].*[a-z].*[0-9].*[\\W_]" findall { } = not ] [ drop ] until print
Björn Lindqvist
fuente
Puede que esté malinterpretando la expresión regular, pero creo que algo así ~{}|1234abcdABCDfallará en la expresión regular.
Hand-E-Food
1
No, funcionará:"~{}|1234abcdABCD" 60 cycle "[A-Z].*[a-z].*[0-9].*[\\W_]" findall empty? not => t
Björn Lindqvist
Tomaré tu palabra por ello. :-)
Hand-E-Food
1

C - 154 caracteres

char p[16],c,f,w;main(){srand(time());while(f^15){c=p[15]=f=0;while(c^15){w=33+rand()%94;f|=w
>96&&w<123?1:w>47&&w<59?2:w>64&&w<91?4:8;p[c++]=w;}}puts(p);}

¿Cómo no me gusta srand()? Déjame contar las formas.

Oberon
fuente
1

Haskell, 192

import System.Random
main=getStdGen>>= \g->(print.(take 15))$until((\x->all(any(`elem`x))[['a'..'z'],['A'..'Z'],['0'..'9'],['!'..'/']++":;<=>?@[\\]^_`{|}~"]).(take 15))tail$randomRs('"','~')g

La cadena impresa tiene comillas alrededor y escapa a la barra invertida y los caracteres de comillas; si eso es inaceptable, printse puede reemplazar conputStrLn por 3 bytes más. Aquí hay una versión más legible:

import System.Random

main = do
    g <- getStdGen
    let chars = randomRs ('"', '~') g
    let password = take 15 $ until (hasChars.(take 15)) tail chars
    print password

hasChars :: String -> Bool
hasChars x = all (any (`elem` x)) $
    [ ['a'..'z']
    , ['A'..'Z']
    , ['0'..'9']
    , "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~"
    ]

Es bastante sencillo, sólo se crea un infinito / lista de perezoso de caracteres ASCII aleatorios en el rango '!'de '~', a continuación, se deja caer a cabo el primer elemento hasta que los primeros 15 caracteres tienen al menos un carácter de cada cadena de caracteres necesarios.

usuario3175123
fuente
1

Excel VBA, 209 bytes

For i = 1 To 15
x = x + Chr(Int(90 * Rnd + 33))
Next
p = "^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*(_|[^\w])).+$"
With New RegExp
.Pattern = p
Set m = .Execute(x)
If m.Count = 0 Then
MsgBox "redo"
Else
MsgBox x
End If
End With

Genera aleatoriamente 15 caracteres ASCII, por lo que todas las combinaciones posibles son posibles. Luego usa un patrón de expresión regular para verificar si contiene al menos uno de cada criterio.

Si lo hace, se muestra la contraseña, si no se muestra "rehacer".

Crédito a Bart Kiers por el patrón de expresión regular: https://stackoverflow.com/questions/1559751/regex-to-make-sure-that-the-string-contains-at-least-one-lower-case-char- Superior

Wightboy
fuente
0

AutoHotkey 352

global o:={}
loop 4
o[c()]:=o(A_index-1)
loop 11
o[c()]:=o(m(r(),4))
loop 15
s.=o[A_index-1]
msgbox % s
r(){
Random,z
return z
}
m(z,r){
return mod(z,r)
}
c(){
while o[t:=m(r(),15)]!=""
j++
return t
}
o(f){
r0:=48,l0:=10,r1:=97,l1:=l2:=26,r2:=65
r := chr(r%f%+m(r(),l%f%))
if f=3
r:=Substr("``~!@#$%^&*()_+-={}|[]\:"";'<>?,./",m(r(),32)+1,1)
return r
}

Utilizando : solo ejecuta el script

Avi
fuente
0

Python (121 caracteres)

Aprovecha el hecho de que puedes multiplicar listas en Python [1,2,3] * 2 da [1,2,3,1,2,3]. Importaciones aleatorias. Los números en una lista multiplicados por tres son bordes entre los rangos en la tabla ASCII para los caracteres necesarios, por ejemplo, [65, 90] mapas a letras mayúsculas.

print "".join([random.choice([chr(i) for i in range(z[0],z[1])]) for z in [[33,48],[48,58],[58,65],[65,90],[90,123]]* 3])
Pawelmhm
fuente
1
"Debe poder generar todas las permutaciones de todos los caracteres permitidos". No creo que lo haga, ya que los rangos siempre se aplican en el mismo orden ...
Joachim Isaksson
Tienes razón, gracias. De hecho, no noté que los rangos deberían aplicarse en orden aleatorio, deberían mezclarse, lo editaré en un momento.
Pawelmhm
Esto realmente debe incluir import randomen el código.
Mego
0

PHP 5.5 (230 bytes)

echo preg_replace_callback('/./', function ($a)
{
  return chr([rand(33, 126), rand(48, 57), rand(65, 90), rand(97, 122), ord(str_shuffle('`~!@#$%^&*()_+-={}|[]\:";\'<>?,./')[0])][$a[0]]);
}
, str_shuffle(str_pad('1234', 15, 0)));

O en una línea (211 bytes)

echo preg_replace_callback('/./',function($a){return chr([rand(33,126),rand(48,57),rand(65,90),rand(97,122),ord(str_shuffle('`~!@#$%^&*()_+-={}|[]\:";\'<>?,./')[0])][$a[0]]);},str_shuffle(str_pad('1234',15,0)));
MichaelRushton
fuente