Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
2916 connectés 

  FORUM HardWare.fr
  Programmation
  Perl

  Tri d'IP méthode "packed" : question

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Tri d'IP méthode "packed" : question

n°1367912
one_pili
Posté le 16-05-2006 à 17:21:03  profilanswer
 

Bonjour,
 
Dans un script, je trie des adresses IP en utilisant la méthode "packed" décrite (entre autres) ici : http://cpan.belfry.net/authors/id/ [...] erperl.txt.
 

Code :
  1. sub packed {
  2.    pack('C4', split(/\./, $a)) cmp pack('C4', split(/\./, $b));
  3. }
  4. @ip = ('223.1.3.4', '127.0.0.1', '192.168.100.1', '223.1.3.1');
  5. @result = sort packed @ip;
  6. print "Sorted: @result\n";
  7. #
  8. #prints:
  9. #
  10. #------------------- output start---
  11. # Sorted: 127.0.0.1 192.168.100.1 223.1.3.1 223.1.3.4
  12. #
  13. #------------------- output end  ---


 
Tout marche très bien pour trier des adresses IP comme dans le bout de code.
 
En appliquant la même subroutine avec des IP avec le port (écrites sous la forme 192.168.0.100.80), cette routine trie aussi très bien selon les IP mais ne tient pas compte du port (évidement !!).
 
En toute logique, j'obtiens des tris parfaits sur les 4 premiers champs mais nuls sur le 5ème :
 
192.168.0.20.xx
192.168.0.100.995
192.168.0.100.110
192.168.0.100.123
192.168.0.100.80
192.168.0.100.25
192.168.0.101.xx
 
 je voudrais pouvoir modifier la subroutine pour pouvoir trier aussi sur le 5ème champ (contenant le port) pour obtenir  
 
192.168.0.20.xx
192.168.0.100.25
192.168.0.100.80
192.168.0.100.110
192.168.0.100.123
192.168.0.100.995
192.168.0.101.xx
 
Naïvement j'ai essayé de modifier la sub de tri comme ça en supposant qu'elle tiendrait ainsi compte du 5ème champ :

Code :
  1. sub packed {
  2.    pack('C5', split(/\./, $a)) cmp pack('C5', split(/\./, $b));
  3. }


 
Mais mlaheureusement c'est pas comme ça que ça marche ...
 
Si quelqu'un voulait m'expliquer, je serais très content  
- de savoir pourquoi  
- et d'avoir une piste pour une solution.
 
P.S. la routine standard contenue dans la doc Perl (cmp || cmp || cmp || cmp || cmp) ne convient pas très bien vu le nombre d'adresses à trier (> 50'000).

mood
Publicité
Posté le 16-05-2006 à 17:21:03  profilanswer
 

n°1368272
pospos
Posté le 16-05-2006 à 22:09:39  profilanswer
 

pourtant ca doit marcher avec le C5
mais c'est peut etre du au fait que le separateur de port est ':' et non '.'. Donc en remplacant le pattern de plit par /[\.:]/, ou bien meme /\D/ ca devrait passer.
 
Cependant cette methode de tric n'est pas tres optimale car elle va engendrer dans les n log n appels à la sub de tri.
Le mieux est de faire un tri de type GRT (transfomration de la liste, tri tel quel, puis transfomration inverse).
 
Pour cela je te conseil le module Sort::Key, tres efficace.

n°1368831
one_pili
Posté le 17-05-2006 à 15:24:08  profilanswer
 

Merci pospos pour la réponse,
Je vais regarder ce module Sort::Key, de toutes façons, comme tu le soulignes, cette méthode de tri n'est pas la plus rapide.
 
Concernant le séparateur, mes entrées sont déjà "regexées" et ce sont bien des points (et pas des `:' qui séparent les paquets de chiffres (port compris).
 
Par contre, comme tu penses aussi que ça devrait marcher, j'ai essayé autre chose (que j'avais mal précisé dans ma question) : les ports qui accompagnent les adresses sont des nombres de 2  à 5 chiffres ...
J'obtiens des résultats meilleurs en utilisant  `C6' au lieu de `C5' et en partageant le nombre à 5 chiffre du port en un nombre de 3 chiffres et un nombre de 2 chiffres.
 
Là miracle ça trie ...  
Exemple avec `C6' dans la sub :
IP avec port état brut : 10.10.30.20.55640
IP à port transformé : 10.10.30.20.556.40
Et ça trie ... mais imparfaitement :
la liste des valeurs triées est partagées en trois séries (chacunes parfaitements triées)  affichées dans l'ordre 2,1,3 comme ci dessous:
au début : série 2  
10.10.30.20.512.21
...
10.10.30.20.655.17
puis série 1 (retour à 500 sur le 5ème paquet)
10.10.30.20.500.12
...
10.10.30.20.511.98
puis série 3 pour IP suivante
10.10.30.22.186.3
10.10.30.22.203.24
10.10.30.20.334.45
 
Là je comprends plus ... j'espère que Sort::Key fera mieux et si possible plus vite.
 

n°1368979
pospos
Posté le 17-05-2006 à 16:54:36  profilanswer
 

oups ben oui le port ne tiens pas forcement dans un char...
le solution est d'utiliser un entier 'N' (big endian, qui se tri dans le bon sens).
Donc tu prend N5 et ca devrait rouler (et tu peux faire la meme transformation avec Sort::Key)

n°1369015
one_pili
Posté le 17-05-2006 à 17:19:08  profilanswer
 

Wow !!!  
 
Dans le mille !!!
de l'importance de donner les bons éléments dans les questions ...
 
En tous cas, *un grand merci* parceque maitenant ça fonctionne parfaitement.
 
Je vais regarder Sort::Key tranquillement maintenant.


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  Perl

  Tri d'IP méthode "packed" : question

 

Sujets relatifs
VBA-E Question ListBoxpetite question toute bête en java (synchronisation)
methode serializer? ca sert à quoi?Question basique sur les liens ! [résolu]
Localisation PHP, quelle methode ?"méthode" de file homemade
Question simple : Comme faire apparaître / disparaître un calque.Question sur les sockets
[JAVA] [recherche méthode] Object <-> [ ] byte[javascript] Settimeout question
Plus de sujets relatifs à : Tri d'IP méthode "packed" : question


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR