如何使用Perl脚本将little Endian转换为Big Endian?

时间:2011-07-22 18:14:00

标签: perl endianness

我正在使用Perl Win32::SerialPort模块。在这个特殊模块中,我使用输入命令发送数据。我发送到嵌入式系统的数据是使用transmit_char函数的标量数据(数字)(如果它是C它将是整数,但由于它是一种脚本语言,我不知道内部格式是什么perl。我的猜测是perl总是将所有数字存储为32位浮点,这些浮点在发送时由模块调整)。

然后在发送数据后,我使用输入命令接收数据。我收到的数据可能是二进制形式,但perl不知道如何解释它。我像这样使用unpack函数

my $binData = $PortObj->input;
my $hexData = unpack("H*",$binData);

假设我通过串行电缆传输0x4294,这是我正在与之通信的嵌入式系统上的命令,我期望得到0x5245的响应。现在问题在于endianess:当我解压缩时,我得到0x4552,这是错误的。有没有办法通过调整二进制数据来纠正它。我还尝试了h*,它给了我0x5425,这也是不正确的。

注意:我收到的数据一次通过字节发送,LSB先发送

2 个答案:

答案 0 :(得分:7)

Endianess适用于整数(主要)字节的排序。你需要知道整数的大小。

32位无符号示例:

my $bytes = pack('H*', '1122334455667788');
my @n = unpack('N*', $bytes);
# @n = ( 0x11223344, 0x55667788 );

my $bytes = pack('H*', '4433221188776655');
my @n = unpack('V*', $bytes);
# @n = ( 0x11223344, 0x55667788 );

pack。请注意“<”和“>”修饰符来控制字节的字节位置默认字节顺序不是您想要的字符串。

注意:如果您正在从文件中读取,那么您已经有了字节。不要使用pack 'H*'创建字节。

注意:如果您正在阅读该文件,请不要忘记binmode句柄。


关于OP添加到他的帖子的例子:

要从0x5245获取"\x45\x52",请使用unpack("v", $two_bytes)

答案 1 :(得分:2)

这些数据类型是什么? Perl的包具有整数的NV格式说明符,Perl 5.10添加了><修饰符,因此您可以读取短路,浮点数和双精度数(以及一些其他类型)你想要的字节序。

使用这些,您可以读取输入中使用的字节序数据。执行此操作后,您可以在内部显示数据,并且无论如何都可以重新打包它们。

我在Use the > and < pack modifiers to specify the architecture写了这篇文章。