logo Homepage
Pages: [1]
  Imprimer  
Auteur Fil de discussion: Algo en perl pour mettre a jour un dictionnaire bruteforce  (Lu 7521 fois)
alsch
Profil challenge

Classement : 8769/54277

Néophyte
*
Hors ligne Hors ligne
Messages: 3


Voir le profil
« le: 08 Mai 2013 à 22:05:03 »

Bonjour,
Ayant des petits problèmes de gestion de dictionnaires  (dans le cadre des bruteforces ), j'ai décidé de faire un petit script en Perl afin de pouvoir ajouter des mots dans un dictionnaire à partir d'un autre fichier .
Cela permet de créer un plus gros dictionnaire(et plus complet) à partir de tout ceux que vous pouvez trouver a droite et a gauche en evitant les doublons dus au copié collé.

C'est la première fois que je touche a du perl donc si vous avez des idées d'amélioration , je suis tout à fait preneur .
 
Je n'ai pas fini encore le code , je vais ajouter une fonction pour trier le dictionnaire par ordre alphabétique ou par taille. Et je dois aussi implémenter la gestion des Erreurs.La suite sera posté quand elle sera fini(Mais la pour le moment c'est deux semaines d'exams qui m'attende ...).

Après une journée à s'arracher les cheveux à cause d'une erreur d'algo ca donne :



Code:
#!/usr/bin/perl

#dictionnary_update.py by MrStotch


use strict;

my $start_time=time();
my $end_time;
my $run_time;

#if no argument has been passed in the commande line
if(!$ARGV[0])

{
print "you have to enter files\n" ;
print "enter \"--help\" for more help about the prog\n";
}

#if the user
elsif($ARGV[0] eq '--help' || $ARGV[0] eq '-h' || $ARGV[0] eq '?'){
print "Usage:\n";
print "\t -u is to update a file\n";
print "\tdictionary tools original_dictionary_path new_dictionary_path\n\n";
print "\t-d to dectect the double in the file\n";
print "\tdictionary_tools -d file\n\n";
        print "\t-s to sort the words in the file\n";
        print "\tdictionary_tool -s file\n\n";

}

#this part of the programme will check if a word
#is two times in the dictionary


#Permit to sort the dictionnary

elsif($ARGV[0] eq '-s')
{
        print "Sorting the dictionary\n";
        print "To complete\n";
}

elsif($ARGV[0] eq '-u'){

#$old_diction take the value of the second arg that is the
#name of the dictionary which will be update
my $old_diction=$ARGV[1];

#$new_diction will take the value of the third arg that is
#the name of the dictionary which contains the new passwords
my $new_diction=$ARGV[2];

open (OLDDICO, "$old_diction");
open (NEWDICO, $new_diction);
open (OLDDICOWRITE, ">>$old_diction");

#initializasion of $lineold and $linenew
my $lineold="";
my $linenew="";

#this var is used to know if the word is or not
#in the dictionnary
#if it is find $find=1 if not $find=0
my $find=0;



print "\n\nChecking if new passwords from $old_diction have be added to $new_diction\n";

#wile we can read the diction with the new passwords
while(<NEWDICO>)
{
#initialize the value of $find at each start of the loop
$find=0;

#divide the file in line
chomp;

#$linenew take the value of the current line
$linenew=$_;

#while we can read the file
while(<OLDDICO>)
{
#divide the file in line
chomp;

#$lineold take the value of the current line
$lineold=$_;

#if the ẁord is find in the dictionnary
if ($linenew eq $lineold)
{
#$find change its statut to true because the word
#has  benn found
$find=1;

#break the loop
last;
}

}
#if the word is not find it will be added
#at the end of the file
if($find==0)
{
#update the dictio by writing the word
#at the end of the dictionnary
print OLDDICOWRITE "$linenew\n";

print "----> \"$linenew\" has been added\n";
}

#Go back to the start of the dictionnary
seek (OLDDICO,0,0);

}

#Close all files used
close (OLDDICOWRITE);
close(OLDDICO);
        close(NEWDICO);

$end_time=time();
$run_time=$end_time-$start_time;
print "the running time  =>$run_time second\n";

}





Pour l'utilisation , il suffit de faire:
./dictionary_update.pl -u "nom_du_dictionnaire_a mettre_a_jour" "nom_du_dictionnaire_que_vous venez_de_trouver"


Les mots de passes seront ajoutés à la fin de votre fichier.
« Dernière édition: 08 Mai 2013 à 22:08:44 par alsch » Journalisée
the lsd
Administrateur

Profil challenge

Classement : 190/54277

Membre Héroïque
*****
Hors ligne Hors ligne
Messages: 3096

poulping for fun & profit


Voir le profil WWW
« #1 le: 09 Mai 2013 à 16:02:35 »

J'ai eu exactement la même idée il y a quelques années.
J'ai jamais fini de coder le prog, mais sur le principe, je faisais pas un seul gros fichier, mais un par lettre de l'alphabet (+ caractères spéciaux), ça permettait d'aller plus vite pour la recherche de mots existants, et donc pour ajouter des nouveaux mots au dico.

Enjoy

The lsd
Journalisée

Newbie Contest Staff :
The lsd - Th3_l5D (IRC)
Statut :
Administrateur
Citation :
Cartésien désabusé : je pense, donc je suis, mais je m'en fous !
alsch
Profil challenge

Classement : 8769/54277

Néophyte
*
Hors ligne Hors ligne
Messages: 3


Voir le profil
« #2 le: 09 Mai 2013 à 21:23:30 »

Tu veux dire que le programme dispatchais les différents mots dans passe dans des 27 fichiers différents(alphabet et char spec) en fonction de la première lettre?
Je trouve ça vraiment intéressant.

Je n'ai pas d'expérience dans la puissance des algo .
Est ce que tu sais si l'ouverture de fichiers pompe sur le processeur et la mémoire ?

Pour le moment pour deux fichiers de 50Mb(ce qui est assez conséquent pour un dictionnaire (environ 30 millions de mots de chaque cotés,j'avais calculé le nombre d'opération c'est de la folie ) en machine virtuelle ça me prendre 2 heures avec ce procédé codé en perl.


Journalisée
Zitoune

Profil challenge

Classement : 923/54277

Néophyte
*
Hors ligne Hors ligne
Messages: 30


Voir le profil
« #3 le: 14 Mai 2013 à 02:02:32 »

Bonjour,

Je ne suis pas sûr de bien avoir saisi ton problème, mais à première vue (et vu les tailles envisagées), tu pourrais :
- charger ton ancien dictionnaire en mémoire (dans une table de hash, par exemple) :
Code:
my %hash = ();
...
$hash{$mot} = undef;
- charger dans la même table de hash, le dictionnaire que tu veux merger :
Code:
$hash{$mot} = undef;
Le mécanisme de table de hash garantit l'unicité des clés, donc des entrées du dictionnaire.
Ensuite, quelque chose comme :
Code:
foreach (sort { $a cmp $b } (keys %hash)) {
  print NEWDICO ("$_\n");
}
ce qui devrait te trier au passage ton nouveau fichier.

Je n'ai rien testé et c'est brut de décoffrage, mais je pense que cela coûte grosso modo le temps de lecture des fichiers de départ (une fois chacun), le temps d'écriture du fichier résultat, et bien sûr le temps de trier une liste de 50M éléments (aucune idée de ce que cela représente en Perl), c'est-à-dire de l'ordre de quelques minutes. Je veux bien un retour sur ce point
Pour parler de performances que je maîtrise mieux, je suis quasiment certain qu'un programme C utilisant qsort (quitte à passer un peu de temps à virer les entrées doubles après le tri au moment de l'écriture) remplit ce rôle en moins de 5 minutes.
Dans tous les cas, 2 heures pour faire ça me semble astronomique.

Petite remarque : la puissance de Perl permet de faire le tri avec à peu près n'importe quoi, on peut imaginer utiliser dans le foreach :
Code:
sort { length($a) <=> length($b) } (keys %hash)       # pour faire le tri sur la longueur des chaînes
sort { comparison_function() } (keys %hash)            # pour appeler une fonction de comparaison maison (on peut toujours "inliner" le code à la main si on s'en sent le courage

Une fois le fichier trié, la recherche d'un mot par dichotomie est quasi instantanée si le fichier est en RAM (pour 30 M de lignes, il faut au pire 25 essais). Si les fichiers ne tiennent pas en RAM, il faut en effet commencer à ruser en les découpant suivant la première lettre, les 2 premières lettres, ou utiliser des fonctions de hashages de faible entropie (8 bits, par exemple). La dernière solution est fun, mais ça ne simplifie pas du tout l'élaboration des dictionnaires.

Bref, tout ça pour dire que je ne suis pas certain d'avoir fait avancer le schimilibilillick.

Journalisée

Les papillons se brûlent les ailes à la flamme des chandelles, et tout me pousse à croire qu'ils ont raison.
_o_
Relecteur

Profil challenge

Classement : 42/54277

Membre Héroïque
*
Hors ligne Hors ligne
Messages: 1258


Voir le profil
« #4 le: 14 Mai 2013 à 18:59:25 »

foreach (sort { $a cmp $b } (keys %hash)) {

Vu que la fonction utilisée pour le tri est celle par défaut, ça peut être condensé :
Code:
foreach (sort keys %hash) {
Journalisée

Les épreuves de hack de NC sont trop faciles ? Et pourtant ! Bienvenue dans la vraie vie : http://thedailywtf.com/Articles/So-You-Hacked-Our-Site!.aspx
Zitoune

Profil challenge

Classement : 923/54277

Néophyte
*
Hors ligne Hors ligne
Messages: 30


Voir le profil
« #5 le: 14 Mai 2013 à 23:59:05 »

En effet, judicieuse remarque.
Cependant, je trouve ça un tantinet moins clair pour le lecteur, et j'ai toujours peur en Perl de faire des bêtises, vu que c'est assez permissif 
Journalisée

Les papillons se brûlent les ailes à la flamme des chandelles, et tout me pousse à croire qu'ils ont raison.
alsch
Profil challenge

Classement : 8769/54277

Néophyte
*
Hors ligne Hors ligne
Messages: 3


Voir le profil
« #6 le: 16 Mai 2013 à 14:36:04 »

Merci de toutes vos réponse ,
Dès la fin de mes partiels je me remet au travail (pourquoi les exam sont toujours en même temps que les idées de projet   )

Je ferais les essais avec la hash table qui devrait être bcp moins lourd que ce que j'ai fait
Et aussi avec du code C (j'avais pris perl parce que je n'avait jamais mis les pattes dans ce langage)
Et je vais essayer d'exploser la barre des deux heures )
J'ai hâte de me remettre au boulot.

Merci encore

Journalisée
Harthorn

Profil challenge

Classement : 584/54277

Membre Junior
**
Hors ligne Hors ligne
Messages: 59


Voir le profil
« #7 le: 23 Mai 2013 à 17:04:36 »

Une autre solution serait de le faire en Bash:

Code:
#! /bin/bash

cat $1 > tmp
cat $2 >> tmp
sort tmp > tmp2
uniq tmp2 > dico_final
rm tmp*

C'est quand même beaucoup plus simple!
Journalisée

-----BEGIN GEEK CODE BLOCK-----
Version: 3.1
GCS d(+)x s:(-) a-- C+(++) UL++>+++ P L++>+++ !E W++? !N !o K- w--() !O M--(-) !V- PS+ PE Y+ PGP+>++ t(+) !5? X R tv(-) b+ DI D+ G e++>+++ h-- !r z+
------END GEEK CODE BLOCK------
_o_
Relecteur

Profil challenge

Classement : 42/54277

Membre Héroïque
*
Hors ligne Hors ligne
Messages: 1258


Voir le profil
« #8 le: 23 Mai 2013 à 18:02:02 »

C'est quand même beaucoup plus simple!

Franchement ?

Code:
cat $1 $2 | sort | uniq > dico_final

Mais c'était bien essayé. Par contre, faut pas trop lancer ce genre de truc avec des fichiers de plusieurs gigas.

Edit : pour les mauvaises langues, on peut aussi utiliser sort -u, mais je n'aime pas ces commandes qui font des choses qui n'ont rien à voir avec leur fonction de départ.
Journalisée

Les épreuves de hack de NC sont trop faciles ? Et pourtant ! Bienvenue dans la vraie vie : http://thedailywtf.com/Articles/So-You-Hacked-Our-Site!.aspx
Pages: [1]
  Imprimer  
 
Aller à: