2010-06-03 74 views
4

我想變$num轉換成其反向字節順序,並打印出來:如何以反轉字節順序打印變量?

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

這是印刷一些非打印字符和它看起來正確的十六進制編輯器,但我怎麼能得到它在控制檯上可讀?我已經嘗試過這樣的:

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

這使perl的抱怨一個非數字的參數,所以我覺得pack返回一個字符串。任何想法如何根據$num在控制檯上打印0xb7dd1455

回答

7

您需要使用unpack:從Michael Carman

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

評論:請注意,字節順序修飾符(<>)需要Perl V5.10 +。對於舊版本的Perl,您必須改用NVtemplates

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

但是你確定要這樣做嗎? 它是32位特定的。 這個問題乞求一個「你爲什麼問?」爲了建議比你想要解決的問題更好的東西。

1

作爲主要-C程序員誰在Perl涉足,我立即本能切片,並用位運算骰子:

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

但是,這是perl的,毫無疑問的是許多方法來達到同樣的效果,這可能是一個很好的perl習慣用法。

2

您需要使用CORE::unpack()"H"(大寫的H):

H A hex string (high nybble first). 

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

以爲我會附和對於我們這些誰需要檢查格式的二進制文件。當規範顯示非英特爾字節順序(如MySQL .frm規範)中的十六進制值時,這就是我使用的。您可以通過增加系統讀取大小來指定更大的塊。包/解包長度必須是sysread的2倍。偏移量+ = [設置爲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;