web-dev-qa-db-fra.com

Java Itérer les bits dans le tableau d'octets

Comment puis-je itérer des bits dans un tableau d'octets?

32
Hamza Yerlikaya

Vous devez écrire votre propre implémentation de Iterable<Boolean> Qui prend un tableau d'octets, puis crée des valeurs Iterator<Boolean> Qui se souviennent de l'index en cours dans le tableau d'octets et l'index courant dans l'octet courant. Ensuite, une méthode utilitaire comme celle-ci serait utile:

private static Boolean isBitSet(byte b, int bit)
{
    return (b & (1 << bit)) != 0;
}

(où bit varie de 0 à 7). Chaque fois que next() est appelée, vous devez incrémenter votre index de bits dans l'octet actuel et incrémenter l'index d'octets dans le tableau d'octets si vous atteignez "le 9ème bit".

Ce n'est pas vraiment dur - mais un peu pénible. Faites-moi savoir si vous souhaitez un exemple d'implémentation ...

42
Jon Skeet
public class ByteArrayBitIterable implements Iterable<Boolean> {
    private final byte[] array;

    public ByteArrayBitIterable(byte[] array) {
        this.array = array;
    }

    public Iterator<Boolean> iterator() {
        return new Iterator<Boolean>() {
            private int bitIndex = 0;
            private int arrayIndex = 0;

            public boolean hasNext() {
                return (arrayIndex < array.length) && (bitIndex < 8);
            }

            public Boolean next() {
                Boolean val = (array[arrayIndex] >> (7 - bitIndex) & 1) == 1;
                bitIndex++;
                if (bitIndex == 8) {
                    bitIndex = 0;
                    arrayIndex++;
                }
                return val;
            }

            public void remove() {
                throw new UnsupportedOperationException();
            }
        };
    }

    public static void main(String[] a) {
        ByteArrayBitIterable test = new ByteArrayBitIterable(
                   new byte[]{(byte)0xAA, (byte)0xAA});
        for (boolean b : test)
            System.out.println(b);
    }
}
17
Matthew Flaschen

Original:

for (int i = 0; i < byteArray.Length; i++)
{
   byte b = byteArray[i];
   byte mask = 0x01;
   for (int j = 0; j < 8; j++)
   {
      bool value = b & mask;
      mask << 1;
   }
}

Ou en utilisant Java idiomes

for (byte b : byteArray ) {
  for ( int mask = 0x01; mask != 0x100; mask <<= 1 ) {
      boolean value = ( b & mask ) != 0;
  }
}
9
Paul Sonier

Une alternative serait d'utiliser un BitInputStream comme celui que vous pouvez trouver ici et d'écrire du code comme ceci:

BitInputStream bin = new BitInputStream(new ByteArrayInputStream(bytes));
    while(true){
        int bit = bin.readBit();
        // do something
    }
bin.close();

(Remarque: le code ne contient pas de gestion EOFException ou IOException par souci de concision.)

Mais j'irais avec la variante Jon Skeets et le ferais moi-même.

2
the.duckman

Je sais, probablement pas la façon la plus "cool" de le faire, mais vous pouvez extraire chaque bit avec le code suivant.

    int n = 156;

String bin = Integer.toBinaryString(n);
System.out.println(bin);

char arr[] = bin.toCharArray();
for(int i = 0; i < arr.length; ++i) {
    System.out.println("Bit number " + (i + 1) + " = " + arr[i]);
}

10011100

Numéro de bit 1 = 1

Numéro de bit 2 = 0

Numéro de bit 3 = 0

Numéro de bit 4 = 1

Numéro de bit 5 = 1

Numéro de bit 6 = 1

Numéro de bit 7 = 0

Numéro de bit 8 = 0

2
amischiefr

Vous pouvez parcourir le tableau d'octets et, pour chaque octet, utiliser les opérateurs au niveau du bit pour parcourir ses bits.

0
SpaceghostAli

J'avais besoin d'un peu de streaming dans mon application. Ici vous pouvez trouver mon implémentation BitArray. Ce n'est pas un véritable modèle d'itérateur, mais vous pouvez demander 1 à 32 bits à la matrice de manière continue. Il existe également une implémentation alternative appelée BitReader plus loin dans le fichier.

0
akarnokd