2010-06-03 4 views
4

Je suis en train de convertir la $num variable dans son ordre d'octet inverse et l'imprimer:Comment imprimer une variable dans l'ordre des octets inversés?

my $num = 0x5514ddb7; 
my $s = pack('I!',$num); 
print "$s\n"; 

Il est l'impression que certains caractères non-imprimables et dans un éditeur hexadécimal, il semble bien, mais comment puis-je est-il lisible sur la console? Je l'ai déjà essayé ceci:

print sprintf("%#x\n",$s); 

Cela fait perl se plaint d'un argument non-numérique, donc je pense que pack renvoie une chaîne. Des idées comment puis-je imprimer 0xb7dd1455 sur la console, basé sur $num?

Répondre

7

Vous devez utiliser unpack:

my $num = 0x5514ddb7; 
my $s = pack('I<!',$num); 
my $x = unpack('I>!',$s); 
printf("%#x\n",$x); 

Commentaire de Michael Carman: Sachez que les modificateurs d'ordre d'octet (< et >) nécessitent Perl v5.10 +. Pour les anciennes versions de Perl, vous devez utiliser le N et Vtemplates à la place.

2
my $num=0x5514ddb7; 
my $i = unpack('N', pack('V',$num)); 
printf("0x%x\n", $i); 

Mais êtes-vous sûr de vouloir faire ça? Il est spécifique à 32 bits. La question demande un "pourquoi demandez-vous?" afin de suggérer quelque chose de mieux que ce que vous essayez de résoudre.

1

En tant que programmeur pour la plupart-C qui barbote en perl, mes instincts immédiats sont Débiter avec les opérateurs binaires:

$n2 = ($num & 0xff) <<24 
    | ($num & 0xff00) <<8 
    | ($num & 0xff0000) >>8 
    | ($num & 0xff000000) >>24 ; 

Mais, ce Perl étant, il y a sans doute plusieurs façons d'atteindre le même résultat , et il y a probablement un bon idiome perl pour ça.

2

Vous devez utiliser CORE::unpack()"H" (H majuscule):

H A hex string (high nybble first). 

my $num=0x5514ddb7; 
my $s=pack('I!',$num); 
print unpack ("H*", "$s") . "\n"; # b7dd1455 
0

Pensée Je carillon pour ceux d'entre nous qui ont besoin d'examiner au format des fichiers binaires. C'est ce que j'utilise quand la spécification montre les valeurs hexadécimales dans l'ordre des octets non-Intel comme la spécification MySQL .frm. Vous pouvez spécifier des blocs plus gros en augmentant la taille du fichier sysread. Les longueurs pack/unpack doivent être 2 x la valeur sysread. Le décalage + = [défini sur la valeur sysread].

#!/usr/bin/perl 
BEGIN { 
    use Getopt::Long; 

    $reverse=0; 
    GetOptions ("reverse" => \$reverse); 

} 

my $f=STDIN; 
if (int(@ARGV)) 
{ 
    open(IN, $ARGV[0]) or die "Failed to open $ARGV[0] for reading.\n$!"; 
    $f=IN; 
} 

my $count=1; 
my $offset=0; 
my $after_nl=1; 
while (sysread($f,$buf,2)) 
{ 
    my $hex = unpack('H4', $buf); 
    $hex=join("",(split(//,$hex))[2,3,0,1]) unless $reverse; 
    if (($count % 8) == 0) 
    { 
     printf "%s\n", $hex; 
     $after_nl=1; 
     $offset += 2; 
    } 
    else 
    { 
     printf "%08x ", $offset if $after_nl; 
     printf "%s ", $hex; 
     $offset += 2; 
     $after_nl=0; 
    } 

    $count++; 
} 
0
$num = 0x5514ddb7; 
print '0x', sprintf('%08x', $num) =~ /../g; 
Questions connexes