我有两个相关的问题(在Perl中):
我尝试了这个(以及其他变化,但对于我的生活,我无法弄明白):
binmode(OUT);
my $bit = pack("B1", '1');
my $byte = pack("H2", "02");
print OUT $bit . $byte;
使用十六进制编辑器,我看到我得到16位:
1000000000000020
我想要的是9位:
100000020
另外:假设我写出了其中两种模式。这意味着我最终得到9 + 9 = 18位。我不知道如何处理最后一个字节(填充?)
这是压缩和解压缩文件,空间非常宝贵。我希望有一些简单的惯用方法可以做到这一点,我不知道。
答案 0 :(得分: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 );
然后,对于unpad,在此之前删除所有尾随1
位和0
位。
答案 1 :(得分: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^@