2016-10-20 16 views
-2

バイト配列からビットレベルでエンコードされた情報を抽出したいと思います。 どのように私は私の配列と私のモデルと一致することができ、私のモデルはバイト配列からビットを抽出する

Model 
Field 1 - 3 bits 
Field 2 - 7 bits 
Field 3 - 9 bits 
Field 4 - 13 bits 

と私は4つのバイトを含む配列を持っているようなものであると仮定すると?

私はビット操作に関するいくつかの記事を読んでいますが、すべてを理解しているとは本当に分かりません。

+0

あなたのコードはどこですか?あなたが「いくつかの投稿」を読んだ場合、あなたはどのオペレータを使うべきかを知っていました。 – f1sh

+0

フィールドがどのようなタイプであるかを言わずに答えるのは難しいですが、一般的に言えば、BitSetのように思えます。 – yshavit

+0

すべてのフィールドはintです。 私はいくつかの記事を読んだが、私が言ったように、私が読んだことについてはすべて理解していない。特にマスクについて。 – Tibo

答えて

0

私はBitSetオブジェクトを見つけました。これは本当に便利なようです。

public class BytesDecoder { 

    private BitSet bitSetToDecode; 

    /** 
    * BytesDecoder constructor 
    * Init the BitSet used for decoding 
    * @param bytes the byte array to decode 
    */ 
    public BytesDecoder(byte[] bytes) { 
     Log.i("BytesDecoder", "==== FRAME TO DECODE ===="); 
     Log.i("BytesDecoder", Arrays.toString(bytes)); 
     // Translate bytes array as binary 
     String frameBinary =""; 
     for (byte b : bytes) { 
      frameBinary += toBinary(b,8); 
     } 
     Log.i("BytesDecoder", frameBinary); 

     // Init the BitSet with an array of reversed bytes to handle the little endian representation expected 
     bitSetToDecode = BitSet.valueOf(reverse(bytes)); 
    } 

    /** 
    * Decode a part of the byte array between the startIndex and the endIndex 
    * @param startIndex index of the first bit to include 
    * @param endIndex index after the last bit to include 
    * @return the int value of the decoded bits 
    */ 
    public int decode(int startIndex, int endIndex) { 
     int length = endIndex - startIndex; 

     int decodedInt = convert(bitSetToDecode.get(startIndex, endIndex), length); 

     Log.i("BytesDecoder","--- Decoded parameter --- "); 
     Log.i("BytesDecoder",toBinary(decodedInt, length) + " interpreted as " + decodedInt); 

     return decodedInt; 
    } 

    /** 
    * Reverse bit order of each byte of the array 
    * @param data the bytes array 
    * @return the bytes array with bit order reversed for each byte 
    */ 
    private byte[] reverse(byte [] data) { 
     byte [] bytes = data.clone(); 

     for (int i = 0; i < bytes.length; i++) { 
      bytes[i] = (byte) (Integer.reverse(bytes[i]) >>> 24); 
     } 

     return bytes; 
    } 

    /** 
    * Get the binary form of an int 
    * @param num the int number 
    * @param length the bit length 
    * @return the string value of the binary form of the int 
    */ 
    private String toBinary(int num, int length) { 
     StringBuilder sb = new StringBuilder(); 

     for (int i = 0; i < length; i++) { 
      sb.append(((num & 1) == 1) ? '1' : '0'); 
      num >>= 1; 
     } 

     return sb.reverse().toString(); 
    } 

    /** 
    * Convert a BitSet into an int 
    * @param bits the BitSet 
    * @param length the BitSet theorical lenght 
    * @return the int value corresponding 
    */ 
    private int convert(BitSet bits, int length) { 
     int value = 0; 
     // Set the increment to the difference between the therocial length and the effective lenght of the bitset 
     // to take into account the fact that the BitSet just represent significative bits 
     // (i.e instead of 110, the bitset while contains 11 since the 0 is irrelevant in his representation) 
     int increment = length - bits.length(); 

     // Browse the BitSet from the end to the begining to handle the little endian representation 
     for (int i = bits.length() - 1; i >= 0; --i) { 
      value += bits.get(i) ? (1L << increment) : 0L; 
      increment++; 
     } 

     return value; 
    } 
} 

このクラスでは、バイト配列をビットごとにデコードできます。

私はそれが最良の解決策であるかどうかわかりませんが、これは私が望むことをしています。

関連する問題