Perl 中的十六进制转储解析

发布于 2024-09-12 13:33:30 字数 446 浏览 9 评论 0原文

我在文件中有一个消息的十六进制转储,我想将其放入数组中 这样我就可以对其执行解码逻辑。
我想知道这是否是解析如下消息的更简单方法。

37 39 30 35 32 34 35 34 3B 32 31 36 39 33 34 35
3B 32 31 36 39 33 34 36 00 00 01 08 40 00 00 15
6C 71 34 34 73 69 6D 31 5F 33 30 33 31 00 00 00
00 00 01 28 40 00 00 15 74 65 6C 63 6F 72 64 69
74 65 6C 63 6F 72 64 69

请注意,任何行上的数据最多可为 16 个字节。但任何行也可以包含更少的字节(最小:1)
有没有一种漂亮而优雅的方式而不是在 perl 中一次读取 2 个字符?

I have a hex dump of a message in a file which i want to get it in an array
so i can perform the decoding logic on it.
I was wondering if that was a easier way to parse a message which looks like this.

37 39 30 35 32 34 35 34 3B 32 31 36 39 33 34 35
3B 32 31 36 39 33 34 36 00 00 01 08 40 00 00 15
6C 71 34 34 73 69 6D 31 5F 33 30 33 31 00 00 00
00 00 01 28 40 00 00 15 74 65 6C 63 6F 72 64 69
74 65 6C 63 6F 72 64 69

Note that the data can be max 16 bytes on any row. But any row can contain fewer bytes too (minimum :1 )
Is there a nice and elegant way rather than to read 2 chars at a time in perl ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

绝影如岚 2024-09-19 13:33:30

Perl 有一个 hex 运算符,可以为您执行解码逻辑。

十六进制 EXPR

十六进制

将 EXPR 解释为十六进制字符串并返回相应的值。 (要转换可能以 00x0b 开头的字符串,请参阅 oct。)如果省略 EXPR,则使用 $_

打印十六进制'0xAf'; # 打印“175”
打印十六进制“aF”; # 相同的

请记住, split 的默认行为会在空格分隔符,例如

$ perl -le '$_ = "a b c"; print for split'
a
b
c

对于输入的每一行,将其分隔为十六进制值,将值转换为数字,然后 将它们推入数组中以供稍后处理。

#! /usr/bin/perl

use warnings;
use strict;

my @values;
while (<>) {
  push @values => map hex($_), split;
}

# for example
my $sum = 0;
$sum += $_ for @values;
print $sum, "\n";

示例运行:

$ ./sumhex mtanish-input 
4196

Perl has a hex operator that performs the decoding logic for you.

hex EXPR

hex

Interprets EXPR as a hex string and returns the corresponding value. (To convert strings that might start with either 0, 0x, or 0b, see oct.) If EXPR is omitted, uses $_.

print hex '0xAf'; # prints '175'
print hex 'aF'; # same

Remember that the default behavior of split chops up a string at whitespace separators, so for example

$ perl -le '$_ = "a b c"; print for split'
a
b
c

For every line of the input, separate it into hex values, convert the values to numbers, and push them onto an array for later processing.

#! /usr/bin/perl

use warnings;
use strict;

my @values;
while (<>) {
  push @values => map hex($_), split;
}

# for example
my $sum = 0;
$sum += $_ for @values;
print $sum, "\n";

Sample run:

$ ./sumhex mtanish-input 
4196
命硬 2024-09-19 13:33:30

我会一次读取一行,去掉空格,然后使用 pack 'H*' 来转换它。如果不知道您要应用哪种“解码逻辑”,就很难更具体。例如,以下是一个将每个字节转换为十进制的版本:

while (<>) {
  s/\s+//g;
  my @bytes = unpack('C*', pack('H*', $_));
  print "@bytes\n";
}

示例文件的输出:

55 57 48 53 50 52 53 52 59 50 49 54 57 51 52 53
59 50 49 54 57 51 52 54 0 0 1 8 64 0 0 21
108 113 52 52 115 105 109 49 95 51 48 51 49 0 0 0
0 0 1 40 64 0 0 21 116 101 108 99 111 114 100 105
116 101 108 99 111 114 100 105

I would read a line at a time, strip the whitespace, and use pack 'H*' to convert it. It's hard to be more specific without knowing what kind of "decoding logic" you're trying to apply. For example, here's a version that converts each byte to decimal:

while (<>) {
  s/\s+//g;
  my @bytes = unpack('C*', pack('H*', $_));
  print "@bytes\n";
}

Output from your sample file:

55 57 48 53 50 52 53 52 59 50 49 54 57 51 52 53
59 50 49 54 57 51 52 54 0 0 1 8 64 0 0 21
108 113 52 52 115 105 109 49 95 51 48 51 49 0 0 0
0 0 1 40 64 0 0 21 116 101 108 99 111 114 100 105
116 101 108 99 111 114 100 105
南渊 2024-09-19 13:33:30

我认为一次读入两个字符是解析逻辑标记为两个字符单元的流的适当方法。

你有什么理由认为这很丑吗?

如果您尝试提取特定序列,可以使用空白不敏感的正则表达式来实现。

I think reading in two characters at a time is the appropriate way to parse a stream whose logical tokens are two-character units.

Is there some reason you think that's ugly?

If you're trying to extract a particular sequence, you could do that with whitespace-insensitive regular expressions.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文