Search code examples
cbase64bit

how do i convert a normal int to a 12bit long binary code, to then convert it to 2 letters with Base64?


I have multiple positive integers, which all hold numbers that can be represented by 12 bits or less. I need to convert each value of each integer to a 12 bit binary code, and then split each 12 bit binary code into 2 equal parts and convert each part (each is 6 bits long) into a symbol using base64 encoding.

example - let's say i have this: int a = 2572; 2572 is 101000001100 in binary code. now i split 101000001100 into 2 parts of 6 bits each: 101000 and 001100 then i convert each part into a symbol using base64, and i am left with oM, which i want to print.

or if i have: int a = 172 172 is 10101100 in binary code, and that's 8 bits, so now I add extra 4 zeros to make it 12 bit while keeping the value (172): 000010101100 then split into 2 parts: 000010 101100 and convert each to a symbol with base64.

I hope you get the idea, i can only see a very long way of doing this but i am wondering if someone else had already done something like this or if its easier than i think. thanks in advance


Solution

  • One of the simplest ways to do this is using bitwise operations. In this case bitwise AND (&) and right bit shift (>>) are needed. Besides that a lookup table is used.

    Remarks

    • For clarity the bits are grouped in groups of 6.
    • The leading zeros are omitted for readability.

    Short explanation of bitwise AND

    Bitwise and compares two bits. The resulting bit is 1 if and only if both bits of the input were 1. Example from the question:

    Bitwise AND

    a =         101000 001100
                       111111
    firstPart =        001100
    
    a =          101000 001100
                 111111 000000
    secondPart = 101000 000000
    

    firstPart is now the desired value. The bits of secondPart however, have to be shifted to the right by 6 places, after which the 6 bits at the end are removed and 6 zeros are added to the beginning:

    Bit shift

    secondPart = 101000 000000
    shift: =            101000 000000
    result: =    000000 101000
    

    More information and explanations can be found on the internet (e.g wikipedia).

    Lookup table The lookup table is used to convert the numbers to the corresponding character. The index corresponds to the base64 value.

    Example code

    #include <stdio.h>
    
    int main()
    {
    
        char base64LookupTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
        /* integers are positive, so use unsigned int*/
        unsigned int a = 2572;
    
        /*
        First take the last 6 bits by performing bitwise and.
        This results in 'firstPart' being equal to the last 6 bits of a.
        */
        unsigned int firstPart = a & 0x3F; // 111111 in binary
    
        /*
        Secondly, taking the next 6 bits in the same way and
        shifting them to the right. This results in 'secondPart'
        being equal to the second last 6 bits of a.
        */
        unsigned int secondPart = a & 0xFC0; // 111111000000 in binary
        secondPart >>= 6;
    
        /*
        Print the result by looking up the corresponding characters.
        The index corresponds to the base64 value, so that filling 
        in the found value gives the correct character.
        */
        printf("%c%c\n", base64LookupTable[secondPart], base64LookupTable[firstPart]);
    }