これを説明する最善の方法がわかりません。
基本的に、特定のプロトコルを必要とするバッファに書き込もうとしています。最初の 2 バイトは、「10000001」と「11111110」(ビットごと) です。これらの 2 バイトを Perl のファイル ハンドルに書き込むにはどうすればよいですか?
スペルアウトされたバイナリを実際のバイトに変換するには、パック関数にB
またはb
(ビットの順序に応じて) を使用する必要があります。
print FILE pack('B*', '1000000111111110');
ただし、バイトが定数の場合は、それらを 16 進数値に変換し\x
、文字列リテラルでエスケープを使用することをお勧めします。
print FILE "\x81\xFE";
バージョン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
読みやすくするために、数字の間の数値リテラルでアンダースコア(アンダーバー)を使用できます。たとえば、2進数を3(などのUnixスタイルのモード引数の場合
0b110_100_100
)または4(のようにニブルを表すため0b1010_0110
)または他のグループでグループ化できます。
あなたは書きたくなるかもしれません
print $fh 0b10000001, 0b11111110;
しかし、出力は
129254
10000001²=129₁₀および11111110₂=254₁₀であるため。
リテラルの値の特定の表現、つまり2つの符号なしバイトとしての表現が必要です。そのためには、オクテットpack
×2のテンプレートで使用します。読みやすくするためにアンダースコアを追加し、便利なサブルーチンでラップすると、"C2"
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ユーティリティを使用して表示します。これは、出力にシステムのエンコーディングに制御文字とÞ(ラテン語の小さなとげ)が含まれているためです。
上記の呼び出しは、 marker-demoの出力である入力から各バイトを16進数でレンダリングするようにodに命令します。10000001²=81₁₆および11111110₂=FE₁₆であることに注意してください。左側の列の数字はオフセットです。特別なマーカーバイトはオフセットゼロから始まり(つまり、すぐに)、正確に2つあります。
どうですか
# open my $fh, ...
print $fh "\x81\xFE"; # 10000001 and 11111110