【问题标题】:Perl Pack Unpack and Reverse Byte OrderPerl Pack 解包和反转字节顺序
【发布时间】:2017-06-20 05:28:16
【问题描述】:

我正在尝试编写一个脚本来在文本文件中查找十六进制字符串并将它们转换为它们的反向字节顺序。我遇到的问题是一些十六进制字符串是 16 位的,有些是 64 位的。我使用 Perl 的包来打包和解包 16 位十六进制数字,效果很好,但 64 位则不行。

print unpack("H*", (pack('I!', 0x20202032))). "\n"; #This works, gives 32202020
#This does not
print unpack("H*", (pack('I!', 0x4f423230313430343239303030636334))). "\n";

我用 q 和 Q 尝试了第二个(我得到 ffffffffffffffff)。我是不是把这一切都搞错了?

作为背景知识,我有一个多 GB 的以管道分隔的文本文件,其中包含以相反字节顺序的十六进制字符串,如上所述。此外,文件的列不标准;有时十六进制字符串出现在一列中,有时出现在另一列中。我需要将十六进制字符串转换为它们的反向字节顺序。

【问题讨论】:

    标签: perl unpack


    【解决方案1】:

    总是use warnings;。如果这样做,您将收到以下消息:

    Integer overflow in hexadecimal number at scratch.pl line 8.
    Hexadecimal number > 0xffffffff non-portable at scratch.pl line 8.
    

    这些可以通过use bigint; 解决,并将您的第二个号码声明更改为hex('0x4f423230313430343239303030636334')

    但是,这个数字仍然太大,pack 'I' 无法处理。

    也许这可以通过简单的字符串操作来完成:

    use strict;
    use warnings;
    
    my @nums = qw(
        0x20202032
        0x4f423230313430343239303030636334
    );
    
    for (@nums) {
        my $rev = join '', reverse m/([[:xdigit:]]{2})/g;
        print "$_ -> 0x$rev\n"
    }
    
    __END__
    

    输出:

    0x20202032 -> 0x32202020
    0x4f423230313430343239303030636334 -> 0x3463633030303932343034313032424f
    

    或者处理非偶数长度的数字:

    my $rev = $_;
    $rev =~ s{0x\K([[:xdigit:]]*)}{
        my $hex = $1;
        $hex = "0$hex" if length($hex) % 2;
        join '', reverse $hex =~ m/(..)/g;
    }e;
    print "$_ -> $rev\n"
    

    【讨论】:

    • 效果很好!谢谢你。对不起,我对 perl 有点陌生。将其应用为正则表达式替换的最佳方法是作为一个简单的子例程,使用“e”开关在每一行的匹配项上运行?
    • perl -n -i reverse_it.pl myfile.txt。在 s{}{} 命令的末尾添加一个 g 标志。 reverse_it.pl 包含上面的最后一个代码段。
    【解决方案2】:

    为了迂腐,您示例中的十六进制数字是 32 位和 128 位长,而不是 16 和 64。如果最长的只有 64 位长,您可以成功使用 Q pack模板如您所愿(前提是您的 perl 已编译为支持 64 位整数)。

    无论如何都可以使用pack/unpack 解决方案(如果添加了reverse - 您还必须从十六进制字符串中删除前导0x 或修剪结果中的最后两个字符):

    print unpack "H*", reverse pack "H*", $hex_string;
    

    以你的价值观为例:

    perl -le 'print unpack "H*", reverse pack "H*", "4f423230313430343239303030636334"'
    3463633030303932343034313032424f
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-11-17
      • 1970-01-01
      • 1970-01-01
      • 2014-09-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-09
      相关资源
      最近更新 更多