【问题标题】:Hex dump parsing in perlperl 中的十六进制转储解析
【发布时间】:2010-08-05 03:17:12
【问题描述】:

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

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 个字符?

【问题讨论】:

    标签: perl parsing hexdump


    【解决方案1】:

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

    hex EXPR

    hex

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

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

    请记住split 的默认行为会在空格分隔符处截断字符串,例如

    $ perl -le '$_ = "a b c";打印拆分'
    一种
    b
    c

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

    #! /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-输入
    4196

    【讨论】:

    • @mtanish 谢谢!我很高兴它有帮助。
    【解决方案2】:

    我会一次读取一行,去掉空格,然后使用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
    

    【讨论】:

      【解决方案3】:

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

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

      如果您尝试提取特定序列,可以使用不区分空格的正则表达式来完成。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-10-19
        • 2018-05-28
        • 2022-11-16
        • 2019-08-16
        • 2010-12-30
        • 1970-01-01
        相关资源
        最近更新 更多