IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage Perl Discussion :

Multiplier une longue chaine hexa


Sujet :

Langage Perl

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    36
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Avril 2005
    Messages : 36
    Points : 36
    Points
    36
    Par défaut Multiplier une longue chaine hexa
    Bonjour,

    je ne sais pas trop comment m'y prendre...

    J'ai une chaine héxadécimale (env. 60 caracteres), et je dois calculer son double et l'afficher.

    Je voulais la convertir en décimale pour que ca soit plus simple a multiplier par 2...

    J'ai :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    $test = "A12F4....5012B";                  
    $test = hex("$test"); 
    $test = $test*2;
    $test = sprintf("%x",$test);
    print "Double Hexa : $test\n";
    Au final je dois donc obtenir :
    "1425E...A0256"

    Je rencontre comme pb "Integer overflow in hex number", qui apparement me dit que je dépasse la taille autorisée.

    Un petit coup de main ne serait pas refus.

    Merci.

  2. #2
    Membre chevronné

    Homme Profil pro
    Responsable projets techniques
    Inscrit en
    Février 2003
    Messages
    980
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Responsable projets techniques
    Secteur : Biens de consommation

    Informations forums :
    Inscription : Février 2003
    Messages : 980
    Points : 1 894
    Points
    1 894
    Par défaut
    Peut-être en passant plutôt par du binaire ? La conversion se fait simplement, et la multiplication aussi :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    #!/usr/bin/perl
     
    use strict;
    use warnings;
     
    my $test="A12F4A12F4A12F4A12F4A12F4A12F4A12F4A12F4A12F4A12F4A12F4A12F4";
    my $test2="";
     
    #conversion binaire
    $test=~s/(.)/sprintf("%.4b",hex($1))/eg;
     
    #multiplication par 2
    $test2="000".$test."0";
     
    #conversion retour en hexa
    $test2=~s/(....)/sprintf("%x",oct("0b".$1))/eg;
     
    print "test2 (hex): $test2 \n";
    Il y a sûrement moyen de faire plus propre: je laisse les pros du perl parler !

    Sur un petit cas de test ($test="A12F4" soit 660212 en décimal) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $ perl test3.pl
    test2 (hex): 1425e8
    et 1425e8 en hexa vaut bien 1320424 en décimal qui vaut bien 660212 * 2 =)

  3. #3
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    36
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Avril 2005
    Messages : 36
    Points : 36
    Points
    36
    Par défaut
    En effet, pour une taille de 8 caracteres la fonction hex() marche très bien.

    Pour mon cas, je viens d'essayer ta fonction et elle ne retrourne que des "0"

    Sinon c'est une très bonne idée de passer par une converrsion binaire. je vais bosser dessus pour voir.

    Merci.

  4. #4
    Membre chevronné

    Homme Profil pro
    Responsable projets techniques
    Inscrit en
    Février 2003
    Messages
    980
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Responsable projets techniques
    Secteur : Biens de consommation

    Informations forums :
    Inscription : Février 2003
    Messages : 980
    Points : 1 894
    Points
    1 894
    Par défaut
    Etrange, ça marche chez moi :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $ perl test3.pl
    test2 (hex): 1425e9425e9425e9425e9425e9425e9425e9425e9425e9425e9425e9425e8
    hex() ne convertit qu'un seul caractère à la fois... donc ça devrait passer, c'est étrange que ça ne marche pas chez toi : tu as bien copié mon code ?

    L'exemple de 8 caractères, c'était juste pour pouvoir vérifier le résultat j'ai fait le test avec 60 comme tu peux le voir au dessus =)

    Tu peux lancer ce programme stp (j'ai ajouté des prints pour voir):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    #!/usr/bin/perl
     
    use strict;
    use warnings;
     
    my $test="A12F4A12F4A12F4A12F4A12F4A12F4A12F4A12F4A12F4A12F4A12F4A12F4";
    my $test2="";
    print "test (hex): $test \n";
     
    #conversion binaire
    $test=~s/(.)/sprintf("%.4b",hex($1))/eg;
    print "test (bin): $test \n";
     
    #multiplication par 2
    $test2="000".$test."0";
    print "test2 (bin): $test2 \n";
     
    #conversion retour en hexa
    $test2=~s/(....)/sprintf("%x",oct("0b".$1))/eg;
    print "test2 (hex): $test2 \n";
    chez moi, j'ai ça:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    $ perl test3.pl
    test (hex): A12F4A12F4A12F4A12F4A12F4A12F4A12F4A12F4A12F4A12F4A12F4A12F4
    test (bin): 1010000100101111010010100001001011110100101000010010111101001010000100101111010010100001
    0010111101001010000100101111010010100001001011110100101000010010111101001010000100101111010010100001
    0010111101001010000100101111010010100001001011110100
    test2 (bin): 000101000010010111101001010000100101111010010100001001011110100101000010010111101001010
    0001001011110100101000010010111101001010000100101111010010100001001011110100101000010010111101001010
    000100101111010010100001001011110100101000010010111101000
    test2 (hex): 1425e9425e9425e9425e9425e9425e9425e9425e9425e9425e9425e9425e8

  5. #5
    Membre confirmé Avatar de iblis
    Inscrit en
    Janvier 2007
    Messages
    510
    Détails du profil
    Informations personnelles :
    Âge : 57

    Informations forums :
    Inscription : Janvier 2007
    Messages : 510
    Points : 570
    Points
    570
    Par défaut
    C'est dû bien sûr à la limite sur la représentation des entiers.

    Tu peux utiliser Math::BigInt (je te mets le lien pour que tu vois la doc).

    Voilà ce que ça donne (dans le debugger) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    $ perl -d -e0
     
    main::(-e:1):    0
      DB<1> use Math::BigInt
      DB<2> $hx = Math::BigInt->new('0xA12F4A12F4A12F4A12F4A12F4A12F4A12F4A12F4A12F4A12F4A12F4A12F4')
      DB<3> print $hx->bmul(2)->as_hex
    0x1425e9425e9425e9425e9425e9425e9425e9425e9425e9425e9425e9425e8
      DB<4>
    Ou alors le faire à la main.

  6. #6
    Membre chevronné

    Homme Profil pro
    Responsable projets techniques
    Inscrit en
    Février 2003
    Messages
    980
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Responsable projets techniques
    Secteur : Biens de consommation

    Informations forums :
    Inscription : Février 2003
    Messages : 980
    Points : 1 894
    Points
    1 894
    Par défaut
    Tiens, je savais pas que BigInt proposait aussi de la conversion

    Question con (j'ai pas regardé en détail) : il y a des restrictions dans cette bibliothèques ?

  7. #7
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    36
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Avril 2005
    Messages : 36
    Points : 36
    Points
    36
    Par défaut
    Alek-C :
    pour ton info, voila ce que j'obtiens :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    test (hex): A12F4A12F4A12F4A12F4A12F4A12F4A12F4A12F4A12F4A12F4A12F4A12F4 
    test (bin): %.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b 
    test2 (bin): 000%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b%.4b0 
    test2 (hex): 0000000000000000000000000000000000000000000000000000000000000
    Et malheureusement, je ne peux pas installer de modules extérieurs, ce script est censé s'exécuter sur n'importe quel poste en local...

  8. #8
    Membre confirmé Avatar de iblis
    Inscrit en
    Janvier 2007
    Messages
    510
    Détails du profil
    Informations personnelles :
    Âge : 57

    Informations forums :
    Inscription : Janvier 2007
    Messages : 510
    Points : 570
    Points
    570
    Par défaut
    Citation Envoyé par mashu Voir le message
    Et malheureusement, je ne peux pas installer de modules extérieurs, ce script est censé s'exécuter sur n'importe quel poste en local...
    Math::BigInt est dans le core. Quelle version de Perl utilises-tu ?

  9. #9
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    36
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Avril 2005
    Messages : 36
    Points : 36
    Points
    36
    Par défaut
    J'utilise la version 5.005_03 built for sun4-solaris.

    Enfin j'ai dit ca car qd je compile ca :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    use strict;
    use Time::Local;
    use Math::BigInt;
     
    my $hx = Math::BigInt->new('0xA12F4A12F4A12F4A12F4A12F4A12F4A12F4A12F4A12F4A12F4A12F4A12F4');
    $hx->bmul(2);
    print "$hx";
    j'obtiens :
    et si je mets en plus
    j'ai
    Can't locate object method "as_hex" via package "Math::BigInt"

    Voila.

  10. #10
    Membre confirmé Avatar de iblis
    Inscrit en
    Janvier 2007
    Messages
    510
    Détails du profil
    Informations personnelles :
    Âge : 57

    Informations forums :
    Inscription : Janvier 2007
    Messages : 510
    Points : 570
    Points
    570
    Par défaut
    Ok, donc tu as Math::BigInt (présent dès Perl 5).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    use Math::BigInt;
    my $hx = Math::BigInt->new('0xA12F4A12F4A12F4A12F4A12F4A12F4A12F4A12F4A12F4A12F4A12F4A12F4');
    $hx = $hx->bmul(2);
    print $hx->as_hex;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    0x1425e9425e9425e9425e9425e9425e9425e9425e9425e9425e9425e9425e8

  11. #11
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    36
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Avril 2005
    Messages : 36
    Points : 36
    Points
    36
    Par défaut
    Bon désolé mais ca marche pas.

    En fait, dans mon Math::BigInt->new() je suis obligé de mettre une donnée décimale ("11" ca me retourne "+22")

    Si je mets un hexa ("0xA" ou "A" ca me retourne NaN, qui signifie Not-A-Number)



    Et quoiqu'il arrive, as_hex me retourne "Can't call method "as_hex" without a package or object reference"

  12. #12
    Membre confirmé Avatar de iblis
    Inscrit en
    Janvier 2007
    Messages
    510
    Détails du profil
    Informations personnelles :
    Âge : 57

    Informations forums :
    Inscription : Janvier 2007
    Messages : 510
    Points : 570
    Points
    570
    Par défaut
    Ça doit une être une ancienne version de Math::BigInt (chez moi >= 1.77, selon la version de Perl).

    (Tu peux voir la version du module comme ça :
    Code shell : Sélectionner tout - Visualiser dans une fenêtre à part
    perl -MMath::BigInt -e 'print "$Math::BigInt::VERSION\n"'
    )

    Bon, sinon faut le faire à la main. Au fait, c'est pour quoi en fin de compte (il y a peut être une autre voie) ?

  13. #13
    Membre chevronné

    Homme Profil pro
    Responsable projets techniques
    Inscrit en
    Février 2003
    Messages
    980
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Responsable projets techniques
    Secteur : Biens de consommation

    Informations forums :
    Inscription : Février 2003
    Messages : 980
    Points : 1 894
    Points
    1 894
    Par défaut
    Alors, pour BigInt, je ne sais pas ce qui foire... pour mon script, tu as un problème avec sprintf pour la conversion hexa => bin...

    Je ne connais pas assez Perl 5.00 pour savoir ce qu'il faudrait faire, mais tu peux contourner le problème comme cela :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    #!/usr/bin/perl
     
    use strict;
    use warnings;
     
    my $hex2bin={	'0' => '0000',
    				'1' => '0001',
    				'2' => '0010',
    				'3' => '0011',
    				'4' => '0100',
    				'5' => '0101',
    				'6' => '0110',
    				'7' => '0111',
    				'8' => '1000',
    				'9' => '1001',
    				'A' => '1010',
    				'B' => '1011',
    				'C' => '1100',
    				'D' => '1101',
    				'E' => '1110',
    				'F' => '1111'};
    my $bin2hex={	'0000' => '0',
    				'0001' => '1',
    				'0010' => '2',
    				'0011' => '3',
    				'0100' => '4',
    				'0101' => '5',
    				'0110' => '6',
    				'0111' => '7',
    				'1000' => '8',
    				'1001' => '9',
    				'1010' => 'A',
    				'1011' => 'B',
    				'1100' => 'C',
    				'1101' => 'D',
    				'1110' => 'E',
    				'1111' => 'F'};
    my $test="123456789ABCDEF00000000000000002F4A12F4A12F4A12F4A12F4A12F4A";
    my $test2="";
    print "test (hex): $test \n";
     
    #conversion binaire
    $test=~s/(.)/$hex2bin->{$1}/g;
    print "test (bin): $test \n";
     
    #multiplication par 2
    $test2="000".$test."0";
    print "test2 (bin): $test2 \n";
     
    #conversion retour en hexa
    $test2=~s/(....)/$bin2hex->{$1}/g;
    print "test2 (hex): $test2 \n";
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    $ perl test3.pl
    test (hex): 123456789ABCDEF00000000000000002F4A12F4A12F4A12F4A12F4A12F4A
    test (bin): 000100100011010001010110011110001001101010111100110111101111000000000000000000000000000000000000000000000000000000000000000000101111010010100001001011110100101000010010111101001010000100101111010010100001001011110100101000010010111101001010
    test2 (bin): 0000001001000110100010101100111100010011010101111001101111011110000000000000000000000000000000000000000000000000000000000000000001011110100101000010010111101001010000100101111010010100001001011110100101000010010111101001010000100101111010010100
    test2 (hex): 02468ACF13579BDE00000000000000005E9425E9425E9425E9425E9425E94

  14. #14
    Membre confirmé Avatar de iblis
    Inscrit en
    Janvier 2007
    Messages
    510
    Détails du profil
    Informations personnelles :
    Âge : 57

    Informations forums :
    Inscription : Janvier 2007
    Messages : 510
    Points : 570
    Points
    570
    Par défaut
    Citation Envoyé par Alek-C Voir le message
    Question con (j'ai pas regardé en détail) : il y a des restrictions dans cette bibliothèques ?
    L'auteur du module a des benchmarks (datés, mais ça permet de se faire une idée). Si tu as besoin de performances Math::BigInt::GMP peut prendre le relai, si installé.

    @mashu : la méthode de Alex-C (ajout zéro au binaire) fait exactement ce que tu veux.

  15. #15
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    36
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Avril 2005
    Messages : 36
    Points : 36
    Points
    36
    Par défaut
    Bon on laisse tomber BigInt et sprintf, en effet, je pense aussi que ma version actuelle ne le gère pas.

    Je tiens a vous remercier tous les 2 pour m'avoir filer un coup de main cet aprem.
    Je tiens a féliciter Alek-C qui vient de trouver la réponse à mon pb (multiplier une longue chaine hexa par 2 et l'afficher)
    C'est exactement ce que je voulais.

    Je mets le post en résolu.

    Merci.

  16. #16
    Membre chevronné

    Homme Profil pro
    Responsable projets techniques
    Inscrit en
    Février 2003
    Messages
    980
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Responsable projets techniques
    Secteur : Biens de consommation

    Informations forums :
    Inscription : Février 2003
    Messages : 980
    Points : 1 894
    Points
    1 894
    Par défaut
    Citation Envoyé par iblis Voir le message
    L'auteur du module a des benchmarks (datés, mais ça permet de se faire une idée). Si tu as besoin de performances Math::BigInt::GMP peut prendre le relai, si installé.

    @mashu : la méthode de Alex-C (ajout zéro au binaire) fait exactement ce que tu veux.
    Je pensais plus à des restrictions au niveau des limites des nombres utilisés : est-ce qu'il y a des max, ou est-ce que la bibliothèque est censée permettre de gérer tous les nombres (sans prendre en compte le problème de performance) ? Mais je vais jeter un oeil plus en détail par curiosité

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Parcourir une longue chaine de caractères
    Par SnoT- dans le forum Général JavaScript
    Réponses: 6
    Dernier message: 03/08/2009, 10h48
  2. Charger une image à partir d'une chaine HEXA
    Par Argonz dans le forum Delphi
    Réponses: 4
    Dernier message: 15/03/2007, 08h38
  3. Réponses: 1
    Dernier message: 15/12/2006, 20h07
  4. Réponses: 10
    Dernier message: 17/05/2006, 11h50
  5. Découper une longue chaine
    Par lili_bzh dans le forum Linux
    Réponses: 13
    Dernier message: 23/01/2006, 18h08

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo