在Perl中解码3字节整数

在Perl中解码3字节整数,perl,unpack,Perl,Unpack,我正在读取一个二进制文件格式,它以4个常量检查字节开始,然后是3个八位字节,表示记录数据部分的长度。我可以这样解读: read($fh, $x, 7) or do { last if eof; die "Can't read: $!"; }; my ($type, $l1, $l2, $l3) = unpack("a4 C3", $x); my $length = $l1 << 16 | $l2 << 8 | $l3; read($fh,$x,7)或do{ 最后

我正在读取一个二进制文件格式,它以4个常量检查字节开始,然后是3个八位字节,表示记录数据部分的长度。我可以这样解读:

read($fh, $x, 7) or do {
  last if eof;
  die "Can't read: $!";
};
my ($type, $l1, $l2, $l3) = unpack("a4 C3", $x);
my $length = $l1 << 16 | $l2 << 8 | $l3;
read($fh,$x,7)或do{
最后如果eof;
死亡“无法阅读:$!”;
};
我的($type,$l1,$l2,$l3)=拆包(“a4c3”,$x);

my$length=$l1否,
unpack
不支持3字节(或任意长度)整数,但您可以使用无符号16位big-endian int来节省一些工作量:

my ($type, $l1, $l23) = unpack("a4 Cn", $x);
my $length = $l1 << 16 | $l23;
my($type,$l1,$l23)=解包(“a4 Cn”,$x);

my$length=$l1否,
unpack
不支持3字节(或任意长度)整数,但您可以使用无符号16位big-endian int来节省一些工作量:

my ($type, $l1, $l23) = unpack("a4 Cn", $x);
my $length = $l1 << 16 | $l23;
my($type,$l1,$l23)=解包(“a4 Cn”,$x);

my$length=$l1您可以在字符串中插入一个空字节,以便能够使用“N”格式:

编辑:或分两步解包:

my ($type, $length) = unpack "a4 a3", $x;
$length = unpack "N", "\0" . $length;

您可以在字符串中插入空字节,以便能够使用“N”格式:

编辑:或分两步解包:

my ($type, $length) = unpack "a4 a3", $x;
$length = unpack "N", "\0" . $length;

解决方案:获取类型的方法很好。但是,我建议您将长度单独解包为一个四字节整数,然后丢弃这四个字节中的第一个字节。即使它重叠并丢弃类型的最后一个字节,也会更有效

my $type = unpack("a4", $x);
my $length = unpack("x3N", $x); # skips the first 3 bytes of your original 7-byte string
$length = $length & 0xFFFFFF; # returns only the last 3 bytes of the four-byte integer

解决方案:获取类型的方法很好。但是,我建议您将长度单独解包为一个四字节整数,然后丢弃这四个字节中的第一个字节。即使它重叠并丢弃类型的最后一个字节,也会更有效

my $type = unpack("a4", $x);
my $length = unpack("x3N", $x); # skips the first 3 bytes of your original 7-byte string
$length = $length & 0xFFFFFF; # returns only the last 3 bytes of the four-byte integer


酷。如果我需要更好的表现,我会把它放在我的后口袋里——这可能会让下一个人(可能是我未来的自己)感到困惑。酷。如果我需要更好的表现,我会把它放在我的后口袋里——不过这可能会让下一个人(可能是我未来的自己)感到困惑。