【问题标题】:View Perl Variables as Bytes/Bits以字节/位的形式查看 Perl 变量
【发布时间】:2013-03-14 03:13:59
【问题描述】:

免责声明:自从我做任何 perl 以来已经很久了,所以如果我问/说一些愚蠢的事情,请纠正我。

是否可以查看 perl 变量的字节/位表示?也就是说,如果我说类似

my $foo = 'a';

我知道(认为?)计算机将$foo 视为类似

0b1100010

有没有办法让 perl 打印出变量的二进制表示?

(不求任何实际目的,只是和一位老朋友胡闹,并试图比我在 1997 年更深入地了解它)

【问题讨论】:

    标签: perl binary


    【解决方案1】:

    当然,使用unpack:

    print unpack "B*", $foo;
    

    例子:

    % perl -e 'print unpack "B*", "bar";'
    011000100110000101110010
    

    packperlpacktut 的 perldoc 页面很好地概述了不同表示之间的转换。

    【讨论】:

    • 我刚刚意识到,在 2017 年 perl 已经开箱即用的 ascii 到二进制转换。整洁的!我不知道有这种语言的另一种语言。
    【解决方案2】:

    如果您想要实际的内部结构,可以从名为“perlguts”的文档开始。 perldoc perlguts 或在此处阅读:http://perldoc.perl.org/perlguts.html

    【讨论】:

    • 一个有趣的问题,我跟进了关于Devel::Peek的注释
    【解决方案3】:

    在看到 Andy 解释您的问题的方式之后,我可以接着说 Devel::Peek 有一个 Dump 函数可以显示变量的内部表示。它不会把它带到二进制级别,但如果你对内部感兴趣,你可以看看这个。

    $ perl -MDevel::Peek -e 'my $foo="a";Dump $foo';
    SV = PV(0x7fa8a3004e78) at 0x7fa8a3031150
      REFCNT = 1
      FLAGS = (PADMY,POK,pPOK)
      PV = 0x7fa8a2c06190 "a"\0
      CUR = 1
      LEN = 16
    
    $ perl -MDevel::Peek -e 'my %bar=(x=>"y",a=>"b");Dump \%bar'
    SV = IV(0x7fbc5182d6e8) at 0x7fbc5182d6f0
      REFCNT = 1
      FLAGS = (TEMP,ROK)
      RV = 0x7fbc51831168
      SV = PVHV(0x7fbc5180c268) at 0x7fbc51831168
        REFCNT = 2
        FLAGS = (PADMY,SHAREKEYS)
        ARRAY = 0x7fbc5140f9f0  (0:6, 1:2)
        hash quality = 125.0%
        KEYS = 2
        FILL = 2
        MAX = 7
        RITER = -1
        EITER = 0x0
        Elt "a" HASH = 0xca2e9442
        SV = PV(0x7fbc51804f78) at 0x7fbc51807340
          REFCNT = 1
          FLAGS = (POK,pPOK)
          PV = 0x7fbc5140fa60 "b"\0
          CUR = 1
          LEN = 16
        Elt "x" HASH = 0x9303a5e5
        SV = PV(0x7fbc51804e78) at 0x7fbc518070d0
          REFCNT = 1
          FLAGS = (POK,pPOK)
          PV = 0x7fbc514061a0 "y"\0
          CUR = 1
          LEN = 16
    

    【讨论】:

      【解决方案4】:

      还有一种方法:

      printf "%v08b\n", 'abc';
      

      输出:

      01100001.01100010.0110001
      

      (v 标志是仅 perl 的 printf/sprintf 功能,也适用于 b 以外的数字格式。)

      这与解包建议的字符大于"\xff" 不同:解包将只返回 8 个低位(带有警告),printf '%v...' 将显示所有位:

      $ perl -we'printf "%vX\n", "\cA\13P\x{1337}"'
      1.B.50.1337
      

      【讨论】:

        【解决方案5】:

        您可以使用ord 返回字符的数值,并使用printf%b 格式以二进制形式显示该值。

        print "%08b\n”, ord 'a'
        

        输出

        01100010
        

        【讨论】:

          猜你喜欢
          • 2017-09-14
          • 2012-11-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-02-01
          • 1970-01-01
          • 2017-03-31
          相关资源
          最近更新 更多