Perl:如何将big endian转换为little endian

时间:2013-05-07 15:17:42

标签: perl endianness

此问题已解决。非常感谢你们^^

我的问题和我正在使用的解决方案如下所述。

原始问题:---编辑2013-05-08

我知道我可以通过C ++完成这项任务:

struct {              /* File Header */
    int a;
    int b;
    short c;    
    short d;
} PPPhdr;
PPPhdr head;
fstream fst;
fst.open("file.txt", ios_base::in|ios_base::binary);
fst.read((char*)&head, sizeof(PPPhdr));
SwapInt32(&(head.a));
SwapInt32(&(head.b));
SwapShort(&(head.c));
SwapShort(&(head.d));

所以,基本上SwapInt32会这样做:

0x89346512 -> 0x12653489

SwapShort会这样做:

0x3487 -> 0x8734

现在我的问题是,我怎么能在Perl中做到这一点?

我的方式:

open FH, "<file.txt" or die print "Cannot open file\n";
binmode FH;
read FH, $temp, 12;
($a,$b) = unpack("N2", substr($temp,0,8));
($c,$d) = unpack("n2", substr($temp,8,4));
close(FH);
print "$a\n$b\n$c\n$d\n";

4 个答案:

答案 0 :(得分:2)

您说您的数据是big-endian,但您在解包调用中使用的是i模板(有符号整数值)。您应该使用N(无符号32位大端数字)。您可能需要阅读documentation

答案 1 :(得分:2)

Perl对于有符号的大端整数没有单字符格式。请使用pack 'i>'。 (这至少需要Perl 5.10。)

答案 2 :(得分:1)

你必须打包并反过来打开包装:

print "ok\n" if 0x12653489 == unpack 'L', pack 'N', 0x89346512;

答案 3 :(得分:0)

我做到了。首先,我感觉自己是bigendian还是littleendian。要么读取文件并查看字节序标志(例如TIFF文件中的字节0-1),要么通过

来感知我自己系统的字节序
  $x = pack ("S", 256); 
  $bigendian = ord(substr ($x, 0, 1));    # 1 for bigendian 0 for littleendian

一旦我有了$ bigendian的值,就可以使用变量进行打包和解包:

  $short = $bigendian ? "n" : "v"; 
  $long = $bigendian ? "N" : "V"; 
  ($a,$b) = unpack($long . "2", substr($temp,0,8));
  ($c,$d) = unpack($short . "2", substr($temp,8,4));

nN代表“网络”,该标准要求使用bigendian

vV代表“ Vax”,这是旧的DEC系统,是littleendian