Thread: Converting binary array to Byte array

  1. #1
    Registered User
    Join Date
    Nov 2019
    Posts
    50

    Converting binary array to Byte array

    Hi guys,
    I have binary array called rxbuffer=[11110001010101010101010101010101010101010101000000 00000000001111111110000000000000011111111110000000 00001111111110000000000000001111111111110000000000 11111111110000000000000000000000000000000000000000 000001]; its size not specifically dividable by 8 , I want to convert this rx buffer to type Byte data, I mean by this every 8bit in my rxbuffer convert them to Byte data, could anyone please help me how do I implement that in C?
    my purpose is to get rxbuffer as Byte type array and not binary(0/1) array.

    in other words I want to convert my rxbuffer[] from rxbuffer[] that has binary values to this
    uint8_t rxBuffer[] , for example the output of what I need looks like this:
    uint8_t rxBuffer[] = {5, 1, 2, 3, 4, 5, 0, 0};

    thanks alot!
    Last edited by Brian_Teir; 07-20-2020 at 10:33 AM.

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    > its size not specifically dividable by 8
    So what's your plan for when rxbuffer isn't nicely divisible by 8 ?

    Do this 8 times.
    byte = (byte << 1) | rxbuffer[i++];
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Nov 2019
    Posts
    50
    Quote Originally Posted by Salem View Post
    > its size not specifically dividable by 8
    So what's your plan for when rxbuffer isn't nicely divisible by 8 ?

    Do this 8 times.
    byte = (byte << 1) | rxbuffer[i++];
    So here byte will be an array that has all the values that I converted? and you mean 8 times , in other worse to do 8 iteration by increasing i 8 times?


    for your question if it's not dividable by 8, Im looking for adding zeros from the left till the size of array be dividable by 8, but still not good approach not?

  4. #4
    Registered User
    Join Date
    May 2012
    Posts
    505
    Quote Originally Posted by Brian_Teir View Post
    So here byte will be an array that has all the values that I converted? and you mean 8 times , in other worse to do 8 iteration by increasing i 8 times?


    for your question if it's not dividable by 8, Im looking for adding zeros from the left till the size of array be dividable by 8, but still not good approach not?
    You need to loop in two nested loops. The outer loop represents the byte, the inner loop the bit. The inner loop will be 8 times, the outer loop you can calculate by taking the array size and dividing by eight.

    Then you need special logic for the last byte, which might not be a full number of bits. Zero padding is a reasonable strategy, though remember that you'll probably need to store the number of bits somewhere if zero-padding changes the meaning.

    The modulus operator is a big help. 8 - (bitsize % 8) will give you the number of padding bits to add, unless bitsize is a multiple of 8 in which case you don't need to add any.
    I'm the author of MiniBasic: How to write a script interpreter and Basic Algorithms
    Visit my website for lots of associated C programming resources.
    https://github.com/MalcolmMcLean


  5. #5
    Registered User
    Join Date
    Nov 2019
    Posts
    50
    Quote Originally Posted by Malcolm McLean View Post
    You need to loop in two nested loops. The outer loop represents the byte, the inner loop the bit. The inner loop will be 8 times, the outer loop you can calculate by taking the array size and dividing by eight.

    Then you need special logic for the last byte, which might not be a full number of bits. Zero padding is a reasonable strategy, though remember that you'll probably need to store the number of bits somewhere if zero-padding changes the meaning.

    The modulus operator is a big help. 8 - (bitsize % 8) will give you the number of padding bits to add, unless bitsize is a multiple of 8 in which case you don't need to add any.
    I've done this code but it doesn't give me the correct result, any help? thanks alot.

    unsigned int bitsToBytes(unsigned char *bits)
    {
    unsigned int sum = 0;
    for(int i = 7; i >= 0; i--)
    {
    sum += bits[i];
    sum<<=1;
    }
    return sum;


    }


    int main()
    {
    unsigned char bits[8];
    unsigned int byt;
    byt = bitsToBytes(bits);
    cout << byt; //doesn't give me the right result
    }
    Last edited by Brian_Teir; 07-20-2020 at 01:36 PM.

  6. #6
    Registered User
    Join Date
    Feb 2019
    Posts
    1,078
    I really don't get it... Do you realize that a "byte" is 8 bits, so, by definition "binary data", don't ya?

  7. #7
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    > //doesn't give me the right result
    For starters, your unsigned char bits[8]; contains garbage in the form you've posted it.

    At least try to make your example resemble some data in your first post.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  8. #8
    Registered User
    Join Date
    Nov 2018
    Location
    Amberg in upper palatinate, Bavaria
    Posts
    66
    Hallo Brian_Teir!

    I think it would be better to know from what for a side you want do start to split the whole sentense "rxbuffer" into 8-byte-strings.
    In your example you have 4 times with 50 character long tokens and then a token with a length of 6 character.
    Including the spaces you have a string of 210 characters length.

    First step it would be to separate the 5 tokens form 'rxbuffer' into
    4 times 50 characters and 1 time 6 character.

    50 divide by 8 ist 6 and divison ramainder two.

    So by the 50 characters long tokens you have the problem where you start to separate your 7 decimal values given by characters.
    If you want to start at the left side, here is an possible way to do this:

    Code:
    #include <stdio.h>
    #include <string.h> // strcpy, strtok
    
    // argument 2 is an 2-dimensional array where the tokens are copied into
    // Return-Value: number of tokens where found
    int mixed(char *var, char *delimiter, char numbers[20][60])
    {
     
     printf ("the delimiter is: %s(space)\n", delimiter);
     
      int retval = 0, i = 0;
      char * d;
      d = strtok (var, delimiter);
      
      while (d != NULL)
      {
        strcpy(numbers[i], d); 
        //printf ("i: %2d      String: %s\n", i, numbers[i]);
        i++;
        d = strtok (NULL, delimiter);
       retval++;
      }
     
     return retval;
    }
    
    // copies byte start to end form string allchars to string result_string
    void copychars(char allchars[], char result_string[], int start, int end)
    {
     int i, j = 0;
    
     for (i = start; i <= end; i++)
      {
       result_string[j] = allchars[i];
       result_string[j + 1] = '\0';
       j++; 
      } 
        
    }
    
    /* This function bintodec gets the decimal value of an 8 Byte long binary value
     * The first loop is to get length of given string 'wort'
     * ----------------------------------------------------------------------- */
    void bintodec(unsigned int (*decval), char wort[])
    {
    unsigned int i, ende, dumsm, dumza = 0, testvalue = 1;
     
     for (ende = 0; ende <= 8; ende++)
      if (wort[ende] == '\0') break;
      
     testvalue <<= (ende - 1); /* sets testvalue according to length of  string */
     
     for (i = 0; i <= (ende - 1); i++)
      if ((wort[i] == 'I') || (wort[i] == '1'))
       {
        dumsm = testvalue >> i;
        dumza += dumsm;
       } 
     (*decval) = dumza;
    }
    
    
    int main(int argc, char **argv)
    {
      int rxlen = -1, i, j, k, start, end; 
      int number_of_tokens = 0;
      
      char delimiter[] = " ";
      char rxbuffer_all[220]="11110001010101010101010101010101010101010101000000 00000000001111111110000000000000011111111110000000 00001111111110000000000000001111111111110000000000 11111111110000000000000000000000000000000000000000 000001"; 
      char parts[6][60] = {0};
      //char bitvalue[12] = {0};
      char bitsofchar[5][6][12] = {0};
      unsigned int decvalues[5][6] = {0};
      
       printf("given was this string:\n%s\n", rxbuffer_all);
       
       rxlen = strlen(rxbuffer_all);
        
       printf("Length of given string is: %d byte\n", rxlen); 
       
       number_of_tokens = mixed(rxbuffer_all, delimiter, parts);
       
       printf ("\nNumber of tokens: %d\n-----tokens splited into characters-------\n", number_of_tokens);
      
       for (i = 0; i < number_of_tokens; i++)
        {
         rxlen = strlen(parts[i]);
         printf("token nr: %2d   Token=%s   length=%d\n", i, parts[i], rxlen);
        }
        
      // Now separate tokens into binary values shown as 8-char-string
      // and put this binay values into int-values  
        
      for (k = 0; k < 5; k++)
       {
        printf("\nToken number %d\n", k);    
       for (i = 0, j = 0; i <= 48; i+= 8, j++)
       {
        start = i;
        end = i + 7;
        copychars(parts[k], bitsofchar[k][j], start, end);
        if (strlen( bitsofchar[k][j]) == 0) break;
        bintodec(&decvalues[k][j], bitsofchar[k][j]);
        printf("j=%2d start=%2d   end=%2d   String=%s   decimal value: %u\n", j, start, end, bitsofchar[k][j], decvalues[k][j]);   
       }  
       
       } 
       
        return 0;
    }
    Last edited by rusyoldguy; 07-21-2020 at 09:36 AM.

  9. #9
    Registered User
    Join Date
    Nov 2019
    Posts
    50
    first thanks alot for your effort, secondly I want to understand because understanding is more significant for me. lets assume I have rxbuffer with size 18 so 18/8 is 2 and the reminder is two another bits, lets assume my rxbuffer is this:
    "111111110000000011" , starting from the left I have first 8 bits as 1...1 at it's first token so to convert it to byte regarding to your code the output must be 255 , the next other 8 bits is 0...0 so to convert it to byte according to your code the output must be zero, now according to your code what about "11" two bits how you're converting them to Byte (I mean by Byte a converting to unit8_t type)? could you explain .. thanks alot!
    and the output should be an array like this {1,2,4,5,6} ..every 8bits converted to Byte type(unit8_t type) and output should be an array or list .. like this pattern {1,2,255,0,10,10} , but in your code Im afraid if the output is array or not , for me it's a printing(printf numbers) ..
    Last edited by Brian_Teir; 07-21-2020 at 10:17 AM.

  10. #10
    Registered User
    Join Date
    Nov 2018
    Location
    Amberg in upper palatinate, Bavaria
    Posts
    66
    binary 11 is 3 decimal

    uint8_T is an integer type with 8 bit length. The Data type unsigned char is also 8 bit long If you take int(32bit). for this example i think it doesn't matter anything.
    Like unsigned char uint8_t can take numbers from 0 to 255. signed char from -128 to +127. so it is better to take unsigned char to show a integer value from 0 to 255 as a string.
    In my example the numbers where converted from the string are stored in array:
    [code]
    unsigned int decvalues[5][6] = {0};
    [code]

    they are stored in memory as 32bit values.
    You can change the example to store the converted values into short int or unsigned char.

    for this work you can use this example.

    Code:
    void inttochar(int zuza, unsigned char (*intteile)[4])
    {
     union intpart{
     unsigned int erge;
     unsigned char ipart[4];    
     } ipt;
    
     ipt.erge = zuza;
        
     (*intteile)[0] = ipt.ipart[0];
     (*intteile)[1] = ipt.ipart[1];
     (*intteile)[2] = ipt.ipart[2];
     (*intteile)[3] = ipt.ipart[3];
    }
    you could take this exampe too:
    Code:
    void intzuchar(int zuza, unsigned char (*intteile)[4])
    {
     (*intteile)[0] = zuza & 255;
     (*intteile)[1] = (zuza & (255 << 8)) >> 8;
     (*intteile)[2] = (zuza & (255 << 16)) >> 16;
     (*intteile)[3] = (zuza & (255 << 24)) >> 24;
    }
    The int-value to convert is argument 1, for argument 2 you need a
    4byte unsigned char (or uint8_t) array.


    May be the real length of the field is not 18 bit, it is 3 * 8 = 24 Bit, but the
    other 6 bit are reserved for any thing other.

    But sometimes it is better to work with bitfields.

    example:
    Code:
    /**strinit.cpp shows to work with bitfields */
    #include <stdio.h>
    #include <string.h>
    
    
    /* define a structure with bit fields */
    
    
    struct two_Bytes
    {
       unsigned short lbyte : 8;
       unsigned short hbyte : 8;
    } tb;
     
    /* define a union with bit fields */
    union mixed
    {
      unsigned short ganz;
      struct two_Bytes tb;
    } mx; 
    
     
    int main( ) 
    {
      unsigned short a, b, c;
       
      a = 25;
      b = 255;
      
      c = b + (a << 8); 
      
        
       printf( "Example for struct, Bitfield and uoion\n\n");
       printf( "Memory size occupied by two_Bytes: %lu Byte\n", sizeof(two_Bytes));
       printf( "Memory size occupied by mixed....: %lu Byte\n\n", sizeof(mixed));
    
       mx.tb.hbyte = 25;
       mx.tb.lbyte = 255;
       
       printf( "Sizeof( mxixed ) : %lu Byte\n", sizeof(mx) );
       printf( "eg.tl.hbyte..... : %d\n", mx.tb.hbyte);
       printf( "eg.tl.lbyte..... : %d\n", mx.tb.lbyte);
       printf( "eg.ganz.....     : %d\n", mx.ganz);
       
       printf( "a =  %d\nb = %d\n", a, b);
       
       printf( "result of c = b +(a << 8) : %d\n", c);
         
      return 0;
    }
    An easy example in c++ i found in web for to change a integer value into
    other number systems::

    Code:
    #include <iostream>
    using namespace std;
    
    string toBase (int base, int num)
    {
        static string charset = "0123456789abcdefghijklmnopqrstuvwxyz";
        if (!num)
            return "";
        return toBase(base, num/base) + charset[num%base];
    }
    
    int main() // test
    {
        cout << toBase (10, 27) << endl;  // 27 decimal.
        cout << toBase (2, 27) << endl;   // 27 binary
        cout << toBase (16, 27) << endl;  // 27 hex
        cout << toBase (8, 27) << endl;   // 27 oktal
        cout << toBase (5, 27) << endl;   // 27 in base 5
    }
    Work with binary numbers is a positional system

    I learned it by my self, from an old book.
    Author was
    Egmont colerus

    name of the book was
    "Vom einmaleins zum Integral"
    in english
    title is
    "Mathematics for Everyman"

    see this side:
    Egmont Colerus (Author of Mathematics for Everyman)

    you should read it. Good to learn ( I am 55 years old!)

  11. #11
    Registered User
    Join Date
    Nov 2019
    Posts
    50
    Appreciate your effort , but you're making it hard for me while you explain about other conversions(like other codes you attached but any way thanks alot for your answer )
    So if I understand you unsigned unit8_t is the same as unsigned int yeah? and the array that you store the value of the bytes of the input rxbuffer_all is stored on array called
    Code:
    unsigned int decvalues
    but why the stored array is two denominational array? , in order to output the array that has the bytes values I can just say make the function return decvalues yeah? I tried to update your first attached code but I didn't succeed to write return devalues (to return the array that stores the value bytes-the value that converted them to unit8_t) because the main function must return integer and not an array so Im stuck here

    all what I need is to return the array that has the converted values type BYTE - or in other words unit8_t.

    Last edited by Brian_Teir; 07-21-2020 at 02:08 PM.

  12. #12
    null pointer Structure's Avatar
    Join Date
    May 2019
    Posts
    338

    Post

    Code:
    #include <stdio.h>
    #include <string.h>
    
    #define byteSize 8
    
    int valueOf(char *bits);
    void deBin(char *rx);
    
    int main() {
    
        deBin( "01110100011001010111001101110100" );
    
        return 0;
    }
    
    int valueOf(char *bits) {
        char retChar = '\0';
        int total = 0, counter = 1;
        for (int i=byteSize; i>0; i--) {
            if (bits[i-1] == '1') total += counter;
            if (bits[i-1] != ' ') counter *= 2;        
        }
        return total;
    }
    
    void deBin(char *rx) {
        printf("{ ");
        for (int i=0; i<strlen(rx); i+=byteSize) {
            char nibble[byteSize];
            for (int j=0; j<byteSize; j++) nibble[j] = rx[i+j];
    
                printf( "%x", valueOf(nibble) );
    
            if (i+byteSize != strlen(rx) ) printf(", ");
        }
        printf(" }");
    }
    Last edited by Structure; 07-21-2020 at 03:42 PM.
    "without goto we would be wtf'd"

  13. #13
    Registered User Sir Galahad's Avatar
    Join Date
    Nov 2016
    Location
    The Round Table
    Posts
    277
    Quote Originally Posted by Brian_Teir View Post
    Appreciate your effort , but you're making it hard for me while you explain about other conversions
    If you want a concise answer then I suggest you start by creating a simple and COMPLETE program demonstrating where you're at on the problem. Because as things stand it's a kind of unclear (to me at least) what you're really trying to accomplish.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 5
    Last Post: 01-22-2016, 03:20 AM
  2. converting a binary file to a text array
    By ckeays in forum C Programming
    Replies: 2
    Last Post: 03-29-2011, 03:39 PM
  3. Replies: 8
    Last Post: 11-12-2008, 11:25 AM
  4. Converting an array of byte to an array int
    By chrisfarrugia in forum C Programming
    Replies: 7
    Last Post: 03-05-2008, 08:30 AM
  5. Converting an 8-Byte Array into a Long Representation
    By maththeorylvr in forum C Programming
    Replies: 11
    Last Post: 06-17-2005, 03:21 PM

Tags for this Thread