2016-10-20 11 views
-2

Ich möchte Informationen extrahieren, die auf einer Bit-Ebene von einem Byte-Array codiert sind. Unter der Annahme, dass mein Modell so etwas wieBits aus Byte-Array extrahieren

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

und ich habe ein Array mit 4 Bytes bekam, wie könnte ich mein Modell mit meinem Array überein?

Ich habe ein paar Posts über Bit Manipulation gelesen, aber ich bin nicht wirklich sicher, alles verstanden zu haben.

+0

Wo ist Ihr Code? Wenn Sie "einige Posts" lesen, dann wussten Sie, welche Operatoren zu verwenden sind. – f1sh

+0

Schwer zu beantworten, ohne dass Sie sagen, welcher Typ die Felder sind, aber allgemein gesprochen klingt es wie ein BitSet, was Sie wollen. – yshavit

+0

Alle Felder sind int. Ich habe ein paar Posts gelesen, aber wie gesagt, ich verstehe nicht alles über das, was ich gelesen habe. Besonders über Masken. – Tibo

Antwort

0

Ich habe herausgefunden, BitSet Objekt, das wirklich nützlich zu sein scheint für das, was ich tun möchte.

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; 
    } 
} 

Mit dieser Klasse kann ich ein Byte-Array Stück für Stück dekodieren.

Ich weiß nicht, ob es die beste Lösung ist, aber das mache was ich wollte.