Todas las combinaciones posibles de caracteres y números.
13
Por lo tanto, quiero generar todas las combinaciones posibles de caracteres y números en mayúsculas y minúsculas que pueden formar una cadena de 5 caracteres.
¿Quieres limitarte a ASCII o al script latino? ¿Qué pasa con los signos diacríticos como los acentos (é, â ...)?
Stéphane Chazelas
Gracias por el seguimiento. Publicación original actualizada para aclaraciones.
ardevd
¿Realmente necesita estar en bash? ¿Lo hará un lenguaje como Perl o awk?
terdon
1
Entonces, ¿por qué no simplemente llamar a Perl o Python desde bash? Especialmente con perl, es muy fácil usarlo como una sola línea.
terdon
2
¿Estás tratando de aprender o solo quieres el resultado? En el segundo caso, hay muchos programas que hacen el trabajo como John the Ripper ( john) y similares, lo que le dará muchas posibilidades.
YoMismo
Respuestas:
13
Aquí hay una solución bash que toma la longitud deseada como parámetro (lo haría permute 5en su caso):
#include <stdio.h>//global variables and magic numbers are the basis of good programming
const char* charset ="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
char buffer[50];
void permute(int level){
const char* charset_ptr = charset;if(level ==-1){
puts(buffer);}else{while(buffer[level]=*charset_ptr++){
permute(level -1);}}}
int main(int argc, char **argv){
int length;
sscanf(argv[1],"%d",&length);//Must provide length (integer < sizeof(buffer)==50) as first arg;//It will crash and burn otherwise
buffer[length]='\0';
permute(length -1);return0;}
Ejecutarlo:
make CFLAGS=-O3 permute && time ./permute 5>/dev/null #about 20s on my PC
Los lenguajes de alto nivel apestan en la fuerza bruta (que es básicamente lo que estás haciendo).
@ Stéphane Chazelas Muchas gracias por esa edición. Estaba escribiendo sucio, ignorando las citas "adecuadas", ya que no es necesario en este caso, ¡pero estoy muy agradecido por los atajos!
PSkocik
Probé tu bashsolución. Es muy bonito; Me gusta mucho. Funcionó bien durante aproximadamente 24 horas más o menos antes de notar que mi sistema estaba completamente bloqueado. Intenté algo similar con `python; con un resultado similar, aunque fue considerablemente más rápido.
Cuidado, eso es 6 x 62 5 bytes, entonces 5,496,796,992.
Puedes hacer el mismo bucle bash, pero al bashser el caparazón más lento del oeste, tomará horas:
export LC_ALL=C # seems to improve performance by about 10%
shopt -s xpg_echo # 2% gain (against my expectations)set{a..z}{A..Z}{0..9}for a dofor b dofor c dofor d dofor e do
echo "$a$b$c$d$e"done;done;done;done;done
(en mi sistema, eso genera 700 kiB / s en lugar de 20MiB / s con el perlequivalente).
También siento que se agregaría a la respuesta si tuviera que agregar una forma de enviarlo a un archivo; tal vez como se está generando para que no destruya su RAM, o después de que todo esté en caché en ram
Hellreaver
2
@Hellreaver, todos escriben en un archivo (en stdout, cualquier archivo que esté abierto; si se ejecuta en un terminal, un archivo de dispositivo como /dev/pts/something; y puede cambiar eso con el operador de redirección de shell), no memoria, pero el primero se construye toda la salida en la memoria antes de enviarla (al archivo abierto en stdout).
Stéphane Chazelas
4
Aquí hay una manera de hacerlo únicamente en bash sin tener que consumir 5 GB de memoria:
perl
, es muy fácil usarlo como una sola línea.john
) y similares, lo que le dará muchas posibilidades.Respuestas:
Aquí hay una solución bash que toma la longitud deseada como parámetro (lo haría
permute 5
en su caso):Sin embargo, es dolorosamente lento. ¿Me atrevo a recomendar C? https://youtu.be/H4YRPdRXKFs?t=18s
Ejecutarlo:
Los lenguajes de alto nivel apestan en la fuerza bruta (que es básicamente lo que estás haciendo).
fuente
bash
solución. Es muy bonito; Me gusta mucho. Funcionó bien durante aproximadamente 24 horas más o menos antes de notar que mi sistema estaba completamente bloqueado. Intenté algo similar con `python; con un resultado similar, aunque fue considerablemente más rápido.En
bash
, puedes probar:pero eso llevaría una eternidad y agotaría toda tu memoria. Lo mejor sería usar otra herramienta como
perl
:Cuidado, eso es 6 x 62 5 bytes, entonces 5,496,796,992.
Puedes hacer el mismo bucle
bash
, pero albash
ser el caparazón más lento del oeste, tomará horas:(en mi sistema, eso genera 700 kiB / s en lugar de 20MiB / s con el
perl
equivalente).fuente
/dev/pts/something
; y puede cambiar eso con el operador de redirección de shell), no memoria, pero el primero se construye toda la salida en la memoria antes de enviarla (al archivo abierto en stdout).Aquí hay una manera de hacerlo únicamente en bash sin tener que consumir 5 GB de memoria:
fuente
Esta versión bash todavía no es tan rápida como Perl, pero es aproximadamente cuatro veces más rápida que cinco bucles anidados:
fuente
Puede usar
crunch
(que está disponible al menos en las distribuciones de Kali).fuente
Bueno ... ¿elegante ?, sí (solo una muestra rápida):
Esta expresión completa probablemente bloqueará su computadora:
Una opción sin bloqueo es usar varios bucles:
Llámalo como:
Donde el primer argumento es el número de caracteres y el segundo es la lista (separada por espacios) de los caracteres utilizados.
Eso generará una variable (
loop
) con el script que se ejecutará y la última evaluación ejecutará ese script. Por ejemplo para:El valor de
loop
será:fuente
Gnu Parallel puede hacer combinaciones, consulte https://www.gnu.org/software/parallel/ Algo como esto:
fuente