2009-12-08 2 views
3

J'ai un flux de données adressable uniquement en octets de 8 bits, je veux l'analyser en éléments de 6 bits et le stocker dans un tableau. Existe-t-il des méthodes les mieux connues pour le faire?Comment analyser des éléments n bits à partir d'un tableau adressable par octets

11110000 10101010 11001100 

en

un tableau comme

111100|001010|101011|001100 

(peut avoir zéro rembourrage, tout doit être adressable de cette façon)

et les données est un tableau de 8 bits qui est aussi un multiple de 6 bits, pas vraiment infini

+0

Est-ce un flux constant, sans fin d'éléments de données 5 bits, ou une structure connue qui se répète? – qid

+0

Peut-être y at-il une redondance de correction d'erreur, en supposant toujours le meilleur ;-) – hirschhornsalz

+0

Est-ce que ces octets sont écrits avec le bit le moins significatif en premier ou le plus significatif? En d'autres termes, est-ce (15, 85, 51) ou (240, 170, 204)? –

Répondre

8

Cela dépend de combien de bits d'un octet a sur votre architecture particulière. Sur six architecture peu, il est assez simple :-)

En supposant un 8 bits par l'architecture d'octets, vous aurez à faire quelque chose le long des lignes:

int sixbits(unsigned char* datastream, unsigned int n) { 
    int bitpos = n*6; 
    return (datastream[bitpos/8] >> bitpos%8) // lower part of the five bit group 
     + (datastream[bitpos/8+1] << 8-bitpos%8) // if bitpos%8>2, we need to add some carry bits from the next char 
     & 0x3f;         // and finally mask the lowest 6 bits 
} 

Où n est le n-ième groupe 6 bits . Tout compilateur décent remplacera la division par des décalages et les modules par ands. Utilisez simplement cette fonction dans une boucle pour remplir votre tableau de destination.

+0

+1 Belle solution, beaucoup plus rapide que le mien. Vous pourriez vouloir corriger l'erreur: 'index 'non déclaré' cependant. –

+0

Merci, corrigé. Suppression de certaines parenthèses inutiles, pour faire plus de place pour les commentaires ;-) Pour les personnes non-C, la priorité devrait être claire avec les espaces blancs supplémentaires. – hirschhornsalz

+0

Super, merci beaucoup plus éloquent que le mien – stbtra

1

Vous comptez vos séquences de 5 bits, lisez ea ch octet, décalez les bits en fonction de votre compteur et de la position de mot attendue (en xorant des pièces à partir des mots octets voisins), et formez de nouveaux mots octets correctement alignés que vous traitez ensuite.

J'espère que vous ne vous attendez pas le code ...

0

Que diriez-vous à l'aide d'une struct comme ceci:

struct bit5 
{ 
    unsigned int v1 : 5; 
    unsigned int v2 : 5; 
    unsigned int v3 : 5; 
    unsigned int v4 : 5; 
    unsigned int v5 : 5; 
    unsigned int v6 : 5; 
    unsigned int v7 : 5; 
    unsigned int v8 : 5; 
}; 

Et puis jeté votre tableau d'octets aux struct bit5 tous les 8 octets (40 bits = 8 groupes de 5 bits, correspond à 8 octets) pour obtenir le Morceaux de 5 bits. Dis:

unsigned char* array; // a byte array that you want to convert 
int i; 
struct bit5* pBit5; 

for(i = 0; i < (int)(SIZE_OF_ARRAY/8); i++) 
    pBit5 = (struct bit5*)((int)array + i * 8); 
1

Vous pouvez le faire en utilisant peu tripoter:

#include <stdio.h> 
#include <string.h> 

int main(int argc, char *argv[]) 
{ 
    unsigned char source[3] = { 15, 85, 51 }; 
    unsigned char destination[4]; 
    memset(destination, 0, 4); 
    for (int i = 0; i < (8 * 3); ++i) 
    { 
     destination[i/6] |= ((source[i/8] >> (i % 8) & 1) << (i % 6)); 
    } 

    for (int j = 0; j < 4; ++j) 
     printf("%d ", destination[j]); 
} 

Sortie:

15 20 53 12 

Notez que cela commence à travailler à partir des cinq moins bits significatifs.

 15  85  51 
11110000 10101010 11001100 
111100 001010 101011 001100 
    15  20  53  12 

Pour obtenir plus d'abord importante, faire à la place:

destination[i/6] |= ((source[i/8] >> (7 - (i % 8))) & 1) << (5 - (i % 6)); 

Cela fonctionne comme dans votre exemple, en supposant que vous avez écrit le bit le plus significatif en premier:

240  170  204 
11110000 10101010 11001100 
111100 001010 101011 001100 
60  10  43  12 
+0

Pourquoi est-ce que 'source [6]' quand vous n'utilisez que 3 indices? De plus, je définirais 'unsigned char destinatio [4] = {0};' juste pour la sécurité, mais je ne sais pas si c'est important. –

+0

1) Il était six dans une version antérieure. J'ai juste oublié de le changer. 2) Je metset le tableau de destination à zéro sur la ligne suivante. –

0

Je considérerais en utilisant un BitStream. Cela vous permettra de lire un peu à la fois. Vous pouvez déplacer ce bit directement en place (en utilisant < < n). Il peut ne pas fonctionner aussi bien que la lecture d'un octet de 8 bits à la fois, mais ce serait certainement un code plus propre.

0

Que diriez-vous de cette Union?

union _EIGHT_TO_SIX_ { 

    struct { 

     unsigned char by6Bit0 : 6; 
     unsigned char by6Bit1 : 6; 
     unsigned char by6Bit2 : 6; 
     unsigned char by6Bit3 : 6; 

    } x6; 

    struct { 

     unsigned char by8Bit0; 
     unsigned char by8Bit0; 
     unsigned char by8Bit0; 

    } x8; 
} 

Réglage by8Bitx remplira automatiquement by6Bitx ~~~

Questions connexes