Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 16/04/2011, à 17:44

Thuzhen

Efficacité d'un script Bash

Bonjour tout le monde. smile
Voilà j'ai codé tout à l'heure un petit script qui a pour but de prendre deux fichier non ordonnés contenant des identifiants/pass/hashs et de créer un troisième fichier avec la corresondance login/pass.
Par exemple premier fichier se présente sous cette forme

utilisateur1:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
utilisateur2:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb

le deuxième comme ça :

aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:pass1
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:pass2

et le fichier généré ressemble à :

utilisateur1:pass1
utilisateur2:pass2

J'ai donc codé un petit script de cette manière :

for line in `cat $1`
do
  h=`echo $line | egrep -o ":.{32}" | sed 's/://g'`
  for line2 in `cat $2`
  do
    h2=`echo $line2 | egrep -o ".{32}"`
    p2=`echo $line2 | sed -r 's/.{32}://g'`
    if [ $h = $h2 ]
    then
      echo $line | sed "s/$h/$p2/g" >> $3
    fi
  done
done

Je trouve ce script relativement lent, ce qui ne m'étonne pas vu les boucles imbriquées. Je me demandait donc si il y avait un moyen pour qu'il soit plus rapide.

Sincèrement,
Thüzhen.

EDIT : Avec le premier fichier qui contient 183 lignes et le deuxième 156 un time ./script.sh f1 f2 f3 me retourne 3m27s.

Dernière modification par Thuzhen (Le 16/04/2011, à 17:55)

Hors ligne

#2 Le 16/04/2011, à 19:37

pode

Re : Efficacité d'un script Bash

En perl avec des fonctions de hachage, ç devrait être plus rapide.
Sans la gestion de lignes présentes dans un seul des fichiers, ça donne :

$ cat lecture.pl
#!/usr/bin/perl
use strict;

# fichier 1
my $fichierId = $ARGV[0] || "-";
open FIC1, "< $fichierId" or die "Impossible d'ouvrir le fichier $fichierId : $!";

my %hachage1 = ();
my ( $id, $hache1 );
while( <FIC1> ) {
   ( $id, $hache1 ) = split( ':', $_ );
   $hachage1{ $hache1 } = $id; 
}
close FIC1;

# fichier 2
my $fichierPass = $ARGV[1] || "-";
open FIC2, "< $fichierPass" or die "Impossible d'ouvrir le fichier $fichierPass : $!";

my %hachage2 = ();
my ( $hache2, $motdepasse );
while( <FIC2> ) {
   ( $hache2, $motdepasse ) = split( '[:\n]', $_ );
   $hachage2{ $hache2 } = $motdepasse; 
}
close FIC2;

my ( $cleseule );

for my $cle ( keys %hachage1 ) {
  ( $cleseule ) = split( '\n', $cle );

  my $valeur1 = $hachage1{$cle};
  my $valeur2 = $hachage2{$cleseule};
  print "$valeur1:$valeur2\n";
}
$ cat idhash.in 
utilisateur1:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
utilisateur2:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
$ cat hashpass.in 
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:pass1
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:pass2
$ ./lecture.pl idhash.in hashpass.in 
utilisateur1:pass1
utilisateur2:pass2

Hors ligne

#3 Le 16/04/2011, à 20:11

Thuzhen

Re : Efficacité d'un script Bash

Salut et merci de ta réponse si rapide smile
En réalité je viens de programmer un équivalent en Python, mais c'était pour voir si il y avait moyen de faire plus rapide en bash.
Pour ceux que ça intéresse voici le script python :

#!/usr/bin/python
# -*- coding:utf-8 -*-

import sys

fd1 = open(sys.argv[1],'r')
fd2 = open(sys.argv[2],'r')
fd3 = open(sys.argv[3],'w')

for line in fd1:
    line = line[:-1]
    md5 = line[-32:]
    login = line[:-32]
    for line2 in fd2:
        line2 = line2[:-1]
        password = line2[33:]
        if md5 == line2[:32]:
            fd3.write(login+password+"\n")
            break
    fd2.seek(0)

fd1.close()
fd2.close()
fd3.close()

Pour information ce script prend, avec les même fichiers testés dans mon premier post, 0.031s.

Dernière modification par Thuzhen (Le 16/04/2011, à 20:20)

Hors ligne

#4 Le 17/04/2011, à 02:48

AnsuzPeorth

Re : Efficacité d'un script Bash

J'avais 5 mn à perdre, et je voulais voir les résultats smile

Déjà, le bash ne sera jamais plus rapide que python pour traiter bcp de données.

Ton script bash n'est pas optimisé (le python non plus d'ailleurs !)

Pour créer  2 fichiers de password de 1000 lignes

for ((i=1;i<1000;i++))
do
    md=$(printf '%0*d' 32 $i)
    echo "utilisateur$i:$md" >> ./data1
    echo "$md:pass$i" >> ./data2
done

Ma version bash (je pense qu'on peut faire mieux wink)

#/bin/bash
fpass=$(< ./data2)
while read ligne
do
    name=${ligne%:*}
    md=${ligne#*:}
    li=$(grep $md <<< "$fpass")
    echo $name:${li#*:} >> ./data3
done < ./data1
exit
$ time ./test.sh
real    0m30.146s
user    0m29.270s
sys    0m4.492s

J'ai abandonné avec ton bash après plus d' 1 mn ....


Le script python (je pense qu'on peut faire mieux, j'ai pas non plus cherché wink).

#!/usr/bin/python
# -*- coding:utf-8 -*-

fd1 = open('data1','r')
fd2 = open('data2','r')
fd3 = open('data3','w')

for line in fd1:
    user, md = line.rstrip().split(':')
    for line2 in fd2:
        md1, password = line2.rstrip().split(':')
        if md == md1:
            fd3.write('%s:%s\n' % (user, password) )
            break
            
fd1.close()
fd2.close()
fd3.close()
$ time ./test.py
real    0m0.033s
user    0m0.020s
sys    0m0.012s

$ time ./test.py
real    0m0.035s
user    0m0.024s
sys    0m0.012s

$ time ./test.py
real    0m0.033s
user    0m0.028s
sys    0m0.004s

Avec ton script python:

$ time ./test.py
real    0m0.897s
user    0m0.828s
sys    0m0.020s

$ time ./test.py
real    0m0.870s
user    0m0.828s
sys    0m0.016s

$ time ./test.py
real    0m0.872s
user    0m0.844s
sys    0m0.028s

PS: J'ai essayer avec l'otion -m de grep ou avec sed

li=$(sed -n "/$md/p;q" <<< "$fpass")

Le résultat est un peu prêt pareil, cela varie entre 28 et 30s

Dernière modification par AnsuzPeorth (Le 17/04/2011, à 03:00)


Interface graphique pour bash, python ou autre: glade2script
Support Tchat: http://chat.jabberfr.org/muckl_int/inde … ade2script  (Hors ligne)

Hors ligne