在 Perl 中解码 3 字节整数
Posted
技术标签:
【中文标题】在 Perl 中解码 3 字节整数【英文标题】:Decoding 3-byte integer in Perl 【发布时间】:2013-03-19 23:13:52 【问题描述】:我正在读取一个二进制文件格式,它以 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;
是否有更直接的方法来读取该 3 字节值,而无需中间变量? pack
规范中可能缺少我的东西? pack
除了十六进制编码和其他业余爱好外,我并没有使用太多。
【问题讨论】:
【参考方案1】:您可以在字符串中插入一个空字节,以便能够使用“N”格式:
substr($x, 4, 0, "\0");
my ($type, $length) = unpack "a4 N", $x;
编辑:或者分两步解压:
my ($type, $length) = unpack "a4 a3", $x;
$length = unpack "N", "\0" . $length;
【讨论】:
【参考方案2】:my $type = unpack("a4", $x);
my $len = unpack("N", "\0".substr($x, 4));
或
my ($type, $plen) = unpack("a4 a3", $x);
my $len = unpack("N", "\0$plen");
【讨论】:
【参考方案3】:不,unpack
不支持 3 字节(或任意长度)整数,但您可以使用无符号 16 位 big-endian int 来节省一些工作:
my ($type, $l1, $l23) = unpack("a4 Cn", $x);
my $length = $l1 << 16 | $l23;
【讨论】:
【参考方案4】:解决方案:您获取类型的方法很好。但是,我建议您将长度单独解压缩为一个四字节整数,然后丢弃这四个字节中的第一个字节。即使它重叠并丢弃类型的最后一个字节,这也会更有效。
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
【讨论】:
酷。如果我需要更好的表现,我会把它放在我的后兜里——不过可能会让下一个人(可能是我未来的自己)感到困惑。以上是关于在 Perl 中解码 3 字节整数的主要内容,如果未能解决你的问题,请参考以下文章
编码解码--三种常见字符编码简介:ASCIIUnicode和UTF-8
SyntaxError :( unicode错误)'unicodeescape'编解码器无法解码位置2-3的字节:截断 UXXXXXXXX转义[重复]
'utf8'编解码器在python中解码('utf-8')时无法解码字节0xc3
读取 csv 文件时出错(unicode 错误)“unicodeescape”编解码器无法解码位置 2-3 中的字节:截断 \UXXXXXXXX 转义 [重复]