Как я могу преобразовать 48 шестнадцатеричную строку в байты, используя Perl? - PullRequest
9 голосов
/ 11 марта 2010

У меня есть шестнадцатеричная строка (длина 48 символов), которую я хочу преобразовать в необработанные байты с помощью функции pack , чтобы поместить ее в вектор байтов Win32.

Как я могу сделать это с Perl?

Ответы [ 3 ]

26 голосов
/ 11 марта 2010
my $bytes = pack "H*", $hex;

См. perlpacktut для получения дополнительной информации.

6 голосов
/ 11 марта 2010

Шаги:

  1. Извлечение пар шестнадцатеричных символов из строки.
  2. Конвертировать каждую пару в десятичное число.
  3. Упакуйте число как байт.

Например:

use strict;
use warnings;

my $string = 'AA55FF0102040810204080';
my @hex    = ($string =~ /(..)/g);
my @dec    = map { hex($_) } @hex;
my @bytes  = map { pack('C', $_) } @dec;

Или, выражаясь более компактно:

use strict;
use warnings;

my $string = 'AA55FF0102040810204080';
my @bytes  = map { pack('C', hex($_)) } ($string =~ /(..)/g);
1 голос
/ 26 октября 2012

У меня есть строка:

"61 62 63 64 65 67 69 69 6a"

, который я хочу интерпретировать как шестнадцатеричные значения и отображать их как символы ASCII (эти значения должны воспроизводить строку символов "abcdefghij").

Обычно я пытаюсь написать что-то быстрое, как это:

$ echo "61 62 63 64 65 67 69 69 6a" | perl -ne 'print "$_"; print pack("H2 "x10, $_)."\n";'
61 62 63 64 65 67 69 69 6a
a

... а потом я удивляюсь, почему я получаю только один символ назад :)

Во-первых, позвольте мне отметить, что строка, которую я имею, также может быть представлена ​​в виде шестнадцатеричных значений байтов, которые она занимает в памяти:

$ echo -n "61 62 63 64 65 67 68 69 6a" | hexdump -C
00000000  36 31 20 36 32 20 36 33  20 36 34 20 36 35 20 36  |61 62 63 64 65 6|
00000010  37 20 36 38 20 36 39 20  36 61                    |7 68 69 6a|
0000001a

_ ( NB. По сути, я хочу «преобразовать» указанные выше значения байтов в памяти в качестве входных данных в указанные ниже значения при просмотре с помощью hexdump:

$ echo -n "abcdefghij" | hexdump -C
00000000  61 62 63 64 65 66 67 68  69 6a                    |abcdefghij|
0000000a

... так были получены исходные значения для входной шестнадцатеричной строки. ) _

Что ж, этот учебник по распаковке / распаковке (AKA Как система хранит данные ) оказывается самым полезным для меня, так как упоминает:

Функция pack принимает строку шаблона и список значений [...]

$rec = pack( "l i Z32 s2", time, $emp_id, $item, $quan, $urgent);

Возвращает скаляр, содержащий список значений, сохраненных в соответствии с форматами, указанными в шаблоне [...]

$rec будет содержать следующее (первая строка в десятичном виде, вторая в шестнадцатеричном, третья в качестве символов, где это применимо). Символы трубы обозначают границы полей.

    Offset   Contents (increasing addresses left to right)
         0   160  44  19  62| 41  82   3   0| 98 111 120 101 115  32 111 102
              A0  2C  13  3E| 29  52  03  00| 62  6f  78  65  73  20  6f  66
                                            |  b   o   x   e   s       o   f

То есть, в моем случае $_ является одиночной строковой переменной - тогда как pack ожидает в качестве входных данных список нескольких таких «одиночных» переменных (в дополнение к строке шаблона форматирования); и выводит снова «единственную» переменную (которая, однако, может быть значительным объемом памяти!). В моем случае, если выходная переменная 'single' содержит код ASCII в каждом байте в памяти, тогда я полностью настроен (тогда я мог бы просто напечатать выходную переменную напрямую).

Таким образом, чтобы получить список переменных из строки $_, я могу просто split указать его на пробел - однако, обратите внимание:

$ echo "61 62 63 64 65 67 68 69 6a" | perl -ne 'print "$_"; print pack("H2", split(/ /, $_))."\n";'
61 62 63 64 65 67 68 69 6a
a

... необходимо указать количество элементов, равное pack ed (иначе мы снова получим только один символ); тогда любая из этих альтернатив работает:

$ echo "61 62 63 64 65 67 68 69 6a" | perl -ne 'print "$_"; print pack("H2"x10, split(/ /, $_))."\n";'
61 62 63 64 65 67 68 69 6a
abcdeghij

$ echo "61 62 63 64 65 67 68 69 6a" | perl -ne 'print "$_"; print pack("(H2)*", split(/ /, $_))."\n";'
61 62 63 64 65 67 68 69 6a
abcdeghij
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...