忽略四个字节中的最左边位

Posted

技术标签:

【中文标题】忽略四个字节中的最左边位【英文标题】:Ignoring Leftmost Bit in Four Bytes 【发布时间】:2011-04-15 07:13:58 【问题描述】:

先解释一下原因:

我有一个指向各种 MP3 链接的链接列表,我正在尝试快速读取这些文件的 ID3 信息。我只下载了前 1500 个字节左右,并试图分析这个块中的数据。我遇到了 ID3Lib,但我只能让它在完全下载的文件上工作,并且没有注意到对 Streams 的任何支持。 (如果我错了,请随时指出)

所以基本上,我只能自己解析 ID3 标签。标签的大小可以从文件开头附近的四个字节确定。来自 ID3 网站:

ID3v2 标签大小用四个字节编码,其中最 有效位(第 7 位)在每个字节中设置为零,总共 28 位。零位被忽略,所以一个 257 字节长的标签是 表示为 $00 00 02 01。

所以基本上:

00000000 00000000 00000010 00000001

变成

0000 00000000 00000001 00000001

我对位级操作不太熟悉,想知道是否有人可以对忽略这四个字节中每个字节的最左边位的优雅解决方案有所了解?我正在尝试从中提取一个以 10 为底的整数,这样也可以。

【问题讨论】:

【参考方案1】:

如果你有四个单独的字节,你会想要:

int value = ((byte1 & 0x7f) << 21) |
            ((byte2 & 0x7f) << 14) |
            ((byte3 & 0x7f) << 7) |
            ((byte4 & 0x7f) << 0);

如果您已经在单个 int 中获得了它:

int value = ((value & 0x7f000000) >> 3) |
            ((value & 0x7f0000) >> 2) |
            ((value & 0x7f00) >> 1) |
            (value & 0x7f);

【讨论】:

【参考方案2】:

要清除最高有效位,与 127 (0x7F) 进行“与”运算,这会将除 MSB 之外的所有位。

int tag1 = tag1Byte & 0x7F;  // this is the first one read from the file
int tag2 = tag2Byte & 0x7F;
int tag3 = tag3Byte & 0x7F;
int tag4 = tag4Byte & 0x7F;  // this is the last one

要将其转换为单个数字,请注意每个标记值都是 128 位数字。因此,最不重要的乘以 128^0 (1)、下一个 128^1 (128)、第三重要乘以 (128^2) 等等。

int tagLength = tag4+(tag3<<7)+(tag2<<14)+(tag1<<21)

您提到要将其转换为以 10 为基数。然后您可以将其转换为以 10 为基数,例如用于打印,使用 int 到字符串转换:

String base10 = String.valueOf(tagLength);

【讨论】:

以上是关于忽略四个字节中的最左边位的主要内容,如果未能解决你的问题,请参考以下文章

Oracle ODP.NET 托管驱动程序在 64 位中的运行速度比在 32 位中慢 50-100%

记一次对java对象在内存中的分析

将 char[] 转换为 C++ 中的结构时,计算机会忽略一个字节

R 32 位中的 Java 堆空间错误

位掩码是不是可以与位中的“访问数组”相媲美?

Windows 8.1 64 位中的 IBM MobileFirst 平台安装