簡體   English   中英

Java:如何創建使用掩碼從字節數組中提取整數拆分位的方法

[英]Java: How do I create a Method to extract an Integer's split bits from a byte array using a mask

在解碼某些視頻流標准時,我注意到很多情況下,整數值的位以2-6字節的任何形式提供,但由保留位分隔,如下所示:

// Specification (16 bits)
// -----------------------
// Reserved         1  bit
// Value A [6-7]    2  bit
// Reserved         2  bit
// Value A [4-5]    2  bit
// Reserved         3  bit
// Value A [0-3]    4  bit
// Reserved         2  bit

例如,值185( 101110010xB9 )將如下存儲在兩個字節的數組中:

01000110 00100100

我知道這很麻煩,但這就是這些家伙編碼其數據流的方式。 可以使用以下位操作將其提取

int w = 0;
w |= (0x60 & data[0]) >>> 5;  // extract the first 2 bits shifted to the front
w <<= 2;                      // bump them up 2 bits for the next section
w |= (0x06 & data[0]) >>> 1;  // extract the next 2 bits shifted to the front
w <<= 4;                      // bump them up 4 bits for the last section
w |= (0x3C & data[0]) >>> 2;  // extract the last 4 bits shifted to the front

// w now will equal 10111001 (185)

我想做的是創建一個方法,該方法將接受長度不確定的字節數組和一個Int,該Int表示構成我們試圖提取的值的位的掩碼,這些值構成自提供的規范。 像這樣

public static void testMethod() {

    byte[] data = new byte[] {0x46, 0x24}; // 01000110 00100100 
    int mask = 0x663C;                     // 01100110 00111100
    int x = readIntFromMaskedBytes(data, mask);

}

public static int readIntFromMaskedBytes(byte[] data, int mask) {
    int result = 0;

    // use the mask to extract the marks bits from each
    // byte and shift them appropriately to form an int

    return result;
}

我已經完成了使用原始的“手動”方法進行的項目,但是由於這些事件的數量之多及其復雜性,我不滿意它是否像它那樣干凈。 我很想提出一種更通用的方法來完成同樣的事情。

不幸的是,當涉及到移位的復雜性時,我仍然是一個新手,我希望有人可以就如何最好地實現這一點提供一些建議。

Xela

實際上,我傾向於認為內聯掩碼和移位方法(如果比偽代碼更清晰地實現)比嘗試編寫通用方法更好。 對於有經驗的低級位重擊代碼的開發人員來說,閱讀掩碼移位代碼應該沒有問題。 按照您的提議,使用通用方法的麻煩在於效率會大大降低,而且JIT編譯器難以優化。

順便說一句,這就是我編寫代碼的方式。

// extract and assemble xxxx from yyyy 
int w = ((0x003C & data[0]) >> 2) | 
        ((0x0600 & data[0]) >> 6) | 
        ((0x6000 & data[0]) >> 7);

編輯

我仍然想了解如何將這種通用方法編碼為學習練習。

像這樣:

public static int readIntFromMaskedBytes(int data, int mask) {
    int result = 0;
    int shift = 0;
    while (mask != 0) {
        if (mask & 1) {
            result |= (data & 1) << shift++;
        }
        data >>>= 1;
        mask >>>= 1;
    }
}

如您所見,這將需要多達32個循環迭代才能給出答案。 對於您的示例,我想說這種方法比原始版本慢大約10倍。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM