位移和位掩码 - 示例代码

PDS*_*tat 4 java bit-manipulation

我已经遇到了一些代码,有位掩码0xff0xff00或16位二进制形式00000000 1111111111111111 00000000.

/**
 * Function to check if the given string is in GZIP Format.
 *
 * @param inString String to check.
 * @return True if GZIP Compressed otherwise false.
 */
public static boolean isStringCompressed(String inString)
{
    try
    {
        byte[] bytes = inString.getBytes("ISO-8859-1");
        int gzipHeader = ((int) bytes[0] & 0xff)
            | ((bytes[1] << 8) & 0xff00);
        return GZIPInputStream.GZIP_MAGIC == gzipHeader;
    } catch (Exception e)
    {
        return false;
    }
}
Run Code Online (Sandbox Code Playgroud)

我试图弄清楚在这种情况下使用这些位掩码的目的是什么(针对字节数组).我看不出会有什么不同?

在GZip压缩字符串的上下文中,因为此方法似乎是为GZip编写的幻数35615,8B1F是十六进制和10001011 00011111二进制.

我认为这可以交换字节吗?所以例如说我的输入字符串是\u001f\u008b

bytes[0] & 0xff00
 bytes[0] = 1f = 00011111
          & ff = 11111111
                 --------
               = 00011111

bytes[1] << 8
 bytes[1] = 8b = 10001011
          << 8 = 10001011 00000000

((bytes[1] << 8) & 0xff00)
= 10001011 00000000 & 0xff00
= 10001011 00000000 
  11111111 00000000 &
-------------------
  10001011 00000000
Run Code Online (Sandbox Code Playgroud)

所以

00000000 00011111
10001011 00000000 |
-----------------
10001011 00011111 = 8B1F
Run Code Online (Sandbox Code Playgroud)

对我而言,&在这两种情况下bytes[0] & 0xff,似乎都没有对原始字节做任何事情(bytes[1] << 8) & 0xff00).我错过了什么?

Jes*_*per 6

int gzipHeader = ((int) bytes[0] & 0xff) | ((bytes[1] << 8) & 0xff00);
Run Code Online (Sandbox Code Playgroud)

byteJava是签名的类型.如果你投了byte一个int,它的符号将被延长.这& 0xff是掩盖1从符号扩展中获得的位,有效地将其byte视为无符号.

同样地0xff00,除了字节首先向左移位8位之外.

那么,它的作用是:

  • 取第一个字节,bytes[0]将其转换为int屏蔽符号扩展位(将字节视为无符号)
  • 取第二个字节,将其转换为int,将其向左移8位,并屏蔽符号扩展位
  • 将值与...结合起来 |

请注意,左移有效地交换字节.