2012-03-13 280 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