3

私は2つの関連する問題を抱えています(Perlで):

  1. データをバイナリファイルに次の形式で書き込みます:シングルビットフラグとそれに続く8ビット
  2. 同じフォーマットを読み返す

私はこれを試しました(そして他のバリエーションですが、私の人生ではこれを理解することはできません):

binmode(OUT);
my $bit = pack("B1", '1');
my $byte = pack("H2", "02");
print OUT $bit . $byte;

16進エディタを使用すると、16ビットを取得できます。

1000000000000020

私が欲しいのは9ビットです:

100000020

また、これらのパターンのうち2つを書き出すとします。つまり、最終的に9 + 9=18ビットになります。最後のバイトの処理方法がわかりません(パディング?)

これは、スペースを確保してファイルを圧縮および解凍するためのものです。私は、これを行うための簡単で慣用的な方法があると思っていましたが、私は気づいていませんでした。

4

2 に答える 2

5

ファイルはバイトのシーケンスです。ビットを出力する場合は、何らかの形式のバッファリングを使用する必要があります。

my $bits = '';
$bits .= '1';                                        # Add 1 bit.
$bits .= unpack('B8', pack('C', 0x02));              # Add 8 bits.
$bits .= substr(unpack('B8', pack('C', 0x02)), -6);  # Add 6 bits.

これにより、可能な限り多くのバッファが出力されます。

my $len = ( length($bits) >> 3 ) << 3;
print($fh, pack('B*', substr($bits, 0, $len, '')));

最終的には、残りをフラッシュするために8ビットの倍数になるようにバッファをパディングする必要があります。単にゼロで埋めることができます。

$bits .= "0" x ( -length($bits) % 8 );

ただし、賢い場合は、ファイルが実際に終了する場所を示すために使用できるパディングスキームを思い付くことができます。覚えておいてください、あなたはもはやファイルの長さだけに頼ることはできません。スマートパディングスキームを使用しない場合は、別の方法を使用する必要があります。

スマートパディングスキームの一例は次のとおりです。

$bits .= "0";
$bits .= "1" x ( -length($bits) % 8 );

次に、パッドを解除するには、末尾1のビットとその0前のビットをすべて削除します。

于 2013-01-12T05:46:44.033 に答える
2

Bit :: Vectorを使用して、ビットと変換をさらに簡単に管理できます。

use Bit::Vector;

my $bit = Bit::Vector->new_Bin( 1, '1' );

my $byte     = Bit::Vector->new_Bin( 8, '00000010' );
my $byte_9   = Bit::Vector->new_Bin( 9, '000000010' );
my $nineBits = Bit::Vector->new_Bin( 9, '100000000' );
my $carry    = Bit::Vector->new_Bin( 9, '000000000' );
my $ORed     = Bit::Vector->new_Bin( 9, '000000000' );
my $added    = Bit::Vector->new_Bin( 9, '000000000' );


$ORed->Union($nineBits,$byte_9);

print "bit: 0x". $bit->to_Hex(). "\n";
print "byte 2: 0x". $byte->to_Hex(). "\n";
print "nineBits: 0x". $nineBits->to_Hex(). "\n";
print "nineBits: 0x". $nineBits->to_Bin(). "\n";
print "ORed bit and byte 0x". $ORed->to_Dec(). "\n";

open BINOUT, ">out.bin"
    or die "\nCan't open out.bin for writing: $!\n";

binmode BINOUT;

print BINOUT pack ('B*', $ORed->to_Bin()) ."\n"

これが出力です

>perl bitstuff.pl
bit: 0x1
byte 2: 0x02
nineBits: 0x100
nineBits: 0x100000000
ORed bit and byte 0x-254
>cat out.bin 
\201^@
于 2013-01-12T05:46:54.400 に答える