2

我不确定描述这一点的最佳方式。

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

4

3 回答 3

4

要将拼写出的二进制转换为实际字节,您需要带有or的pack函数(取决于您拥有位的顺序):Bb

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

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

print FILE "\x81\xFE";
于 2012-05-09T07:48:53.253 回答
1

怎么样

# open my $fh, ...
print $fh "\x81\xFE"; # 10000001 and 11111110
于 2012-05-09T07:48:03.753 回答
1

自 5.6.0 版(2000 年 3 月发布)以来,perl 已支持二进制文字,如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

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

你可能会想写

print $fh 0b10000001, 0b11111110;

但输出将是

129254

因为 10000001₂ = 129₁₀ 和 11111110₂ = 254₁₀。

您需要文字值的特定表示,即两个无符号字节。为此,请使用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 铁
0000002

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

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

于 2012-05-09T15:50:19.580 回答