Как преобразовать гекс в строку гекса - PullRequest
0 голосов
/ 13 марта 2012

У меня проблемы с пониманием и использованием ключевого слова 'vec'.

Я читаю журнал, в котором значения хранятся в шестнадцатеричном формате с прямым порядком байтов.В моем коде я должен распаковать различные байты в скаляры, используя ключевое слово 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";

Но я хочу использовать приведенное выше утверждение, как показано ниже.Я не хочу отправлять шестнадцатеричную строку в кавычках.Я хочу использовать скалярный массив hex $ x.Но это не сработает.Как мне преобразовать мой $ x в шестнадцатеричную строку.Это мое требование.

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

Моя конечная цель - прочитать третий бит справа от двухбайтового шестнадцатеричного числа.

Как мне использовать команду 'vec' для этого?

Ответы [ 2 ]

3 голосов
/ 13 марта 2012

Вы совершаете ошибку unpack, вводя $ data в $x перед его использованием при вызове vec. vec ожидает строку, поэтому, если вы укажете число, оно будет преобразовано в строку перед использованием. Вот твой код

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

Формат C pack использует каждое значение в списке источников в качестве кода символа. Это то же самое, что вызывать chr для каждого значения и объединять их. К сожалению, ваши значения выглядят как десятичные, поэтому вы получаете chr(50).chr(65) или "2A". Так как ваши значения имеют порядок байтов, то вы хотите 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 голос
/ 13 марта 2012

Сначала получите число, которое представляют байты.

Если вы начинаете с "\ 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;

(я перечисляю несколько вариантов, потому что мне не ясно, что вы хотите.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...