2012-03-13 278 views
-1

的字符串我有一个问题的理解和使用“VEC”关键字。如何十六进制转换为十六进制

我读其中的值存储在小端十六进制logpacket。在我的代码中,我必须使用unpack关键字将不同的字节解包为标量。

这里是我的问题的一个例子:

my @hexData1 = qw(50 65); 
my $data = pack ('C*', @hexData1); 
my $x = unpack("H4",$data); # At which point the hexadecimal number became a number 
print $x."\n"; 
#my $foo = sprintf("%x", $foo); 

print "$_-> " . vec("\x65\x50", $_, 1) . ", " for (0..15); # This works. 
print "\n"; 

但我想用上面的语句通过以下方式联系。我不想用引号发送十六进制字符串。我想使用十六进制$ x的标量数组。但它不会工作。如何将我的$ x转换为十六进制字符串。这是我的要求。

print "$_-> " . vec($x, $_, 1).", " for (0..15); # This doesn't work. 
print "\n"; 

我最终的目标是读取两个字节十六进制数的右边第三位。

如何使用的“VEC”命令?

回答

3

在使用它之前的数据为$x要制作unpack荷兰国际集团$错误致电vecvec需要一个字符串,所以如果你提供一个数字,在使用之前它会被转换成一个字符串。这里是你的代码

my @hexData1 = qw(50 65); 
my $data= pack ('C*', @hexData1); 

Cpack格式源列表中的字符代码使用的每个值。这与每个值调用chr并将它们连接起来相同。不幸的是,你的值看起来像十进制,所以你得到chr(50).chr(65)"2A"。因为你的价值观是little-endian的,你要的是chr(0x65).chr(0x50)"\x65\x50",所以你必须写

my $data= pack ('(H2)*', reverse @hexData1); 

其中反转数据(考虑到它是小端)的名单和包装它,仿佛它是一个两位十六进制字符串列表(幸运的是)。

现在你已经做得够多了。正如我所说,vec需要一个字符串,所以你可以写

print join ' ', map vec($data, $_, 1), 0 .. 15; 
print "\n"; 

,它会告诉你你所期望的位。要提取从右侧的第3位(假设你的意思是13位,其中最后一位是15位)你想

print vec $data, 13, 1; 
+1

当他有两个以上的字节时,'reverse'将不起作用,就像他在另一篇文章中评论过的那样。 – ikegami 2012-03-16 01:06:28

1

首先,得到代表的字节数。

如果你开始 “\ X50 \ X65”,

my $num = unpack('v', "\x50\x65"); 

如果你开始与 “5065”,

my $num = unpack('v', pack('H*', "5065")); 

如果你开始用 “​​50”, “65”,

my $num = unpack('v', pack('H*', join('', "50","65")); 

然后,提取所需的位。

如果你想第10位,

my $bit = ($num >> 10) & 1; 

如果你想第2位,

my $bit = ($num >> 2) & 1; 

(我列出了几种可能性,因为它不是我清楚你想要什么。)

+0

我想学习如何使用“VEC”关键字。我也不知道如何从$ data中将字符串格式解压缩为标量。另外,原始数据不是字符串格式,因此您不能使用“\ x50 \ x65”。就像我在我的代码中所说的,当我在引号中的'vec'关键字内使用“\ x65 \ x50”时,我得到了我想要的。我想使用'vec'并且想要传递一个标量或一个包含实际字符串而不用引号的变量。谢谢! – Fighter2 2012-03-13 06:23:32

+0

那么你是从“5065”开始的呢?不要告诉我什么不是,告诉我它是什么! (我没有再发布四个猜测,在我继续之前你会清楚) – ikegami 2012-03-13 08:03:03

+1

你说“这不是字符串格式”,你说“这是小端”。这些是相互矛盾的言论。 – ikegami 2012-03-13 08:15:02