Author Options:

Arduino Base64 encoding problem Answered

I have a value that in a later step will be base64 decoded with some other values.
The problem is that the input range for this value is from 0 to 10000 - so outside the 255 for base64.
The line causing me the headache is from a Python script but the math for the Arduino are the same:

NewValue = (((OldValue - OldMin) * NewRange) / OldRange) + NewMin

OldValue can be between 0 and 10000
OldMin = 0
New range can be between 600 and 10000
OldRange can be between 0 and 255
NewMin can be between 400 and 1000

OldValue is used within the base64 decoding process like this:
base64_decode(OldValue, &cmdbuffer[bufindr][strchr_pointer - cmdbuffer[bufindr] + 1], line_raw_length);

As this value is outside the 255 range I need a way to split OldValue into a low and high byte in a way usable for the above base64 decoding.
I found some code that should be able to split but have no real clue how to implement it so it does work.
Here is the splitting code I found:

#include <iostream>
using namespace std;

#define BYTE_T uint8_t
#define TWOBYTE_T uint16_t
#define LOWBYTE(x)          ((BYTE_T)x)
#define HIGHBYTE(x)         ((TWOBYTE_T)x >> 0x8)
#define BYTE_COMBINE(h, l)  (((BYTE_T)h << 0x8) + (BYTE_T)l)

int main() {

    // an array with 16-bit integers
    uint16_t values[5] = {1, 2, 3, 4, 65535};

    // split the 16-bit integers into an array of 8-bit ones
    uint8_t split_values[10]; // notice that you need an array twice as big (16/8 = 2)
    int val_count = 0;
    for (int i=0; i<10; i+=2) {
        split_values[i] = HIGHBYTE(values[val_count]);
        split_values[i+1] = LOWBYTE(values[val_count]);

    // base64 encode the 8-bit values, then decode them back
    // or do whatever you want with them that requires 8-bit numbers

    // then reunite the 8-bit integers to the original array of 16-bit ones
    uint16_t restored[5];
    int rest_count = 0;
    for (int i=0; i<10; i+=2) {
        restored[rest_count] = BYTE_COMBINE(split_values[i], split_values[i+1]);

    for (const auto &i : restored) cout << i << " ";
    cout << endl;

    return 0;

In the original code and with all values just between 0 and 255 the decoding works just fine.
But I had to increase the range for these values so OldValue can be anywhere between 0 and 10000.
Is there any (if possible simple) way to get the decoding done properly?
Or is there anything working I can replace the base64 encoding / decoding with? (problem here is that it has to work with Python and Arduino :( )


The forums are retiring in 2021 and are now closed for new topics and comments.

5 years ago

So you do the usual trick,

1.) MOD number by 64^2 - this is your first digit

2) number -step 1*64^2

3) MOD number 64 - this is your second digit,

Now encode your first and second digits.