2013-05-07 80 views
2

解决此问题。谢谢你这么多家伙^^Perl:如何将big endian转换为little endian

我的问题,我使用下面陈述的解决方案。

原来的问题:---主编2013年5月8日

我知道我可以用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"; 
+1

你能告诉什么输入和预期输出是十六进制什么? – choroba 2013-05-07 15:20:23

+0

0x89346512 - > 0x12653489 ---这就是我想要做的 – sflee 2013-05-08 00:09:52

回答

2

你说你的数据是大端,但您使用的是解包呼叫i模板(一个符号的整数值)。你应该使用N(一个无符号的32位big-endian数字)。您可能想要阅读documentation

+0

谢谢我已经试过这样: '$ TEMP =解压( “N”,$ TEMP);'' 打印$温度;' 这个结果相同: '$ TEMP =解压( “I>”,$ TEMP);'' 打印$温度;' 这是不是我想要的。 – sflee 2013-05-07 23:58:01

+0

是的,你是对的,我解决了我的问题,非常感谢。 – sflee 2013-05-08 05:07:11

+0

一个跟进问题。如何转换一个有符号的32位big-endian数字? – sflee 2013-05-08 05:19:22

2

Perl对于有符号的big-endian整数没有单字符格式。为此,请使用pack 'i>'。 (这至少需要Perl的5.10。)

+0

谢谢,我已经试过这样:
'$温度=解压( “I>”,$ TEMP);'
'$打印温度;'
但得到的答复是不是我想要的。
接下来我应该做什么? – sflee 2013-05-07 23:50:19

+0

是的,你是对的,我解决了我的问题,非常感谢。 – sflee 2013-05-08 05:07:30

1

你收拾它,并解压反过来:

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

非常感谢。 – sflee 2013-05-08 05:08:11