在Perl中将位向量转换为二进制

时间:2012-05-09 07:42:12

标签: perl binary

我不确定描述这个的最好方法。

基本上我正在尝试写入需要某种协议的缓冲区。我想要的前两个字节是“10000001”和“11111110”(逐位)。如何将这两个字节写入Perl中的文件句柄?

3 个答案:

答案 0 :(得分:4)

要将拼写的二进制文件转换为实际字节,您希望pack函数具有Bb(取决于您输入的位数):

print FILE pack('B*', '1000000111111110');

但是,如果字节是常量,则最好将它们转换为十六进制值,并使用字符串文字\x转义:

print FILE "\x81\xFE";

答案 1 :(得分:1)

怎么样

# open my $fh, ...
print $fh "\x81\xFE"; # 10000001 and 11111110

答案 2 :(得分:1)

自5.6.0版(2000年3月发布)以来,perl支持binary literals中记录的perldata

  

数字文字以下列任何浮点或整数格式指定:

12345
12345.67
.23E-10        # a very small number
3.14_15_92     # a very important number
4_294_967_296  # underscore for legibility
0xff           # hex
0xdead_beef    # more hex
0377           # octal (only numbers, begins with 0)
0b011011       # binary
     

您可以在数字之间的数字文字中使用下划线(underbars)以便易读。例如,您可以将二进制数字按三分组(对于Unix样式模式参数,如0b110_100_100)或四分组(表示半字节,如0b1010_0110)或其他组。

你可能想写

print $fh 0b10000001, 0b11111110;

但输出将是

129254

因为10000001 2 = 129 10和11111110 2 = 254 10。

您需要文字值的特定表示,即两个无符号字节。为此,使用pack模板"C2",八位字节乘以2。添加下划线以提高可读性并将其包装在方便的子例程中

sub write_marker {
  my($fh) = @_;
  print $fh pack "C2", 0b1000_0001, 0b1111_1110;
}

作为快速演示,请考虑

binmode STDOUT or die "$0: binmode: $!\n";  # we'll send binary data
write_marker *STDOUT;

运行时
$ ./marker-demo | od -t x1

输出

0000000 81 fe
0000002

如果它不熟悉,od实用程序在这里用于表示目的,因为输出包含一个控制字符和我系统编码中的Þ(拉丁小刺)。

上面的调用命令 od 以十六进制的形式呈现每个字节的输入,这是 marker-demo 的输出。注意10000001 2 = 81 1和11111110 2 = FE 17。左侧列中的数字是偏移量:特殊标记字节从偏移零开始(即立即),并且恰好有两个。