Toutes les combinaisons possibles de caractères et de chiffres
13
Je veux donc générer toutes les combinaisons possibles de caractères minuscules et majuscules et de nombres pouvant constituer une chaîne de 5 caractères.
Possibilités: a..z, A..Z et 0..9.
Existe-t-il une manière élégante de le faire en bash?
Voulez-vous vous limiter à l'ASCII ou au script latin? Et les diacritiques comme les accents (é, â ...)?
Stéphane Chazelas
Merci pour le suivi. Mise à jour du message d'origine pour clarification.
ardevd
Est - il vraiment besoin d'être en bash? Est-ce qu'une langue comme Perl ou awk fera l'affaire?
terdon
1
Alors pourquoi ne pas simplement appeler Perl ou Python depuis bash? Surtout avec perl, il est très facile de l'utiliser comme une doublure.
terdon
2
Essayez-vous d'apprendre ou voulez-vous simplement le résultat? Dans le second cas, il existe de nombreux programmes qui font le travail comme John the Ripper ( john) et autres, ce qui vous offrira de nombreuses possibilités.
YoMismo
Réponses:
13
Voici une solution bash qui prend la longueur souhaitée comme paramètre (vous feriez permute 5dans votre cas):
#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;}
Exécuter:
make CFLAGS=-O3 permute && time ./permute 5>/dev/null #about 20s on my PC
Les langages de haut niveau aspirent au forçage brutal (ce qui est essentiellement ce que vous faites).
@ Stéphane Chazelas Merci beaucoup pour cette retouche. J'écrivais sale, ignorant les citations "correctes" car ce n'est pas nécessaire dans ce cas, mais je suis très reconnaissant pour les raccourcis!
PSkocik
J'ai essayé ta bashsolution. C'est très gentil; Je l'aime beaucoup. Cela a bien fonctionné pendant environ 24 heures avant de remarquer que mon système était complètement verrouillé. J'ai essayé quelque chose de similaire avec `python; avec un résultat similaire, bien que ce fut beaucoup plus rapide.
Attention c'est 6 x 62 5 octets donc 5 496 796 992.
Vous pouvez faire la même boucle bash, mais bashétant l'obus le plus lent de l'ouest, cela va prendre des heures:
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
(sur mon système, qui sort à 700 kio / s contre 20 Mo / s avec l' perléquivalent).
Je pense également que cela ajouterait à la réponse si vous deviez ajouter un moyen de le produire dans un fichier; peut-être au fur et à mesure qu'il est généré pour ne pas détruire votre RAM, ou après que tout est mis en cache dans le ram
Hellreaver
2
@Hellreaver, ils écrivent tous dans un fichier (vers stdout, quel que soit le fichier ouvert; s'il est exécuté dans un terminal, un fichier de périphérique comme /dev/pts/something; et vous pouvez le changer avec l'opérateur de redirection shell), pas de mémoire, mais le premier construit toute la sortie en mémoire avant de la sortir (vers le fichier ouvert sur stdout).
Stéphane Chazelas
4
Voici un moyen de le faire uniquement en bash sans avoir à réduire 5 Go de mémoire:
perl
, il est très facile de l'utiliser comme une doublure.john
) et autres, ce qui vous offrira de nombreuses possibilités.Réponses:
Voici une solution bash qui prend la longueur souhaitée comme paramètre (vous feriez
permute 5
dans votre cas):C'est douloureusement lent, cependant. Oserais-je recommander C? https://youtu.be/H4YRPdRXKFs?t=18s
Exécuter:
Les langages de haut niveau aspirent au forçage brutal (ce qui est essentiellement ce que vous faites).
la source
bash
solution. C'est très gentil; Je l'aime beaucoup. Cela a bien fonctionné pendant environ 24 heures avant de remarquer que mon système était complètement verrouillé. J'ai essayé quelque chose de similaire avec `python; avec un résultat similaire, bien que ce fut beaucoup plus rapide.Dans
bash
, vous pouvez essayer:mais cela prendrait une éternité et épuiserait toute votre mémoire. Le mieux serait d'utiliser un autre outil comme
perl
:Attention c'est 6 x 62 5 octets donc 5 496 796 992.
Vous pouvez faire la même boucle
bash
, maisbash
étant l'obus le plus lent de l'ouest, cela va prendre des heures:(sur mon système, qui sort à 700 kio / s contre 20 Mo / s avec l'
perl
équivalent).la source
/dev/pts/something
; et vous pouvez le changer avec l'opérateur de redirection shell), pas de mémoire, mais le premier construit toute la sortie en mémoire avant de la sortir (vers le fichier ouvert sur stdout).Voici un moyen de le faire uniquement en bash sans avoir à réduire 5 Go de mémoire:
la source
Cette version bash n'est toujours pas aussi rapide que Perl mais elle est environ quatre fois plus rapide que cinq boucles imbriquées:
la source
Vous pouvez utiliser
crunch
(qui est disponible au moins sur les distributions Kali).la source
Eh bien ... élégant ?, oui (juste un échantillon rapide):
Cette expression complète bloquera probablement votre ordinateur:
Une option non bloquante consiste à utiliser plusieurs boucles:
Appelez ça comme:
Où le premier argument est le nombre de caractères et le second est la liste (séparée par des espaces) des caractères utilisés.
Cela va construire une variable (
loop
) avec le script à exécuter et le dernier eval exécutera ce script. Par exemple pour:La valeur de
loop
sera:la source
Gnu Parallel peut faire des combinaisons voir https://www.gnu.org/software/parallel/ Quelque chose comme ceci:
la source