2010-06-03 71 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;