【问题标题】: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 为底的整数,这样也可以。

【问题讨论】:

    标签: c# bit id3


    【解决方案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);
      

      【讨论】:

        猜你喜欢
        • 2020-09-22
        • 1970-01-01
        • 2016-12-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-10-04
        • 1970-01-01
        • 2011-03-13
        相关资源
        最近更新 更多