Base64 Decode Snippet in C++

Base64 decode snippet in C++

See Encoding and decoding base 64 with C++.

Here is the implementation from that page:

/*
base64.cpp and base64.h

Copyright (C) 2004-2008 René Nyffenegger

This source code is provided 'as-is', without any express or implied
warranty. In no event will the author be held liable for any damages
arising from the use of this software.

Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:

1. The origin of this source code must not be misrepresented; you must not
claim that you wrote the original source code. If you use this source code
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.

2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original source code.

3. This notice may not be removed or altered from any source distribution.

René Nyffenegger rene.nyffenegger@adp-gmbh.ch

*/

static const std::string base64_chars =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/";


static inline bool is_base64(unsigned char c) {
return (isalnum(c) || (c == '+') || (c == '/'));
}

std::string base64_encode(unsigned char const* bytes_to_encode, unsigned int in_len) {
std::string ret;
int i = 0;
int j = 0;
unsigned char char_array_3[3];
unsigned char char_array_4[4];

while (in_len--) {
char_array_3[i++] = *(bytes_to_encode++);
if (i == 3) {
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
char_array_4[3] = char_array_3[2] & 0x3f;

for(i = 0; (i <4) ; i++)
ret += base64_chars[char_array_4[i]];
i = 0;
}
}

if (i)
{
for(j = i; j < 3; j++)
char_array_3[j] = '\0';

char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
char_array_4[3] = char_array_3[2] & 0x3f;

for (j = 0; (j < i + 1); j++)
ret += base64_chars[char_array_4[j]];

while((i++ < 3))
ret += '=';

}

return ret;

}
std::string base64_decode(std::string const& encoded_string) {
int in_len = encoded_string.size();
int i = 0;
int j = 0;
int in_ = 0;
unsigned char char_array_4[4], char_array_3[3];
std::string ret;

while (in_len-- && ( encoded_string[in_] != '=') && is_base64(encoded_string[in_])) {
char_array_4[i++] = encoded_string[in_]; in_++;
if (i ==4) {
for (i = 0; i <4; i++)
char_array_4[i] = base64_chars.find(char_array_4[i]);

char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];

for (i = 0; (i < 3); i++)
ret += char_array_3[i];
i = 0;
}
}

if (i) {
for (j = i; j <4; j++)
char_array_4[j] = 0;

for (j = 0; j <4; j++)
char_array_4[j] = base64_chars.find(char_array_4[j]);

char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];

for (j = 0; (j < i - 1); j++) ret += char_array_3[j];
}

return ret;
}

Convert base64 decoded string to unsigned char[32]

Gracchus:

Here it is. Enjoy!

#include <iostream>
#include <string>

struct BASE64_DEC_TABLE {
signed char n[256];

BASE64_DEC_TABLE() {
for(int i=0; i<256; ++i) n[i] = -1;
for(unsigned char i='0'; i<='9'; ++i) n[i] = 52+i-'0';
for(unsigned char i='A'; i<='Z'; ++i) n[i] = i-'A';
for(unsigned char i='a'; i<='z'; ++i) n[i] = 26+i-'a';
n['+'] = 62;
n['/'] = 63;
}
int operator [] (unsigned char i) const { return n[i]; }
};

size_t Base64Decode(const std::string& source, void* pdest, size_t dest_size) {
static const BASE64_DEC_TABLE b64table;
if(!dest_size) return 0;
const size_t len = source.length();
int bc=0, a=0;
char* const pstart = static_cast<char*>(pdest);
char* pd = pstart;
char* const pend = pd + dest_size;
for(size_t i=0; i<len; ++i) {
const int n = b64table[source[i]];
if(n == -1) continue;
a |= (n & 63) << (18 - bc);
if((bc += 6) > 18) {
*pd = a >> 16; if(++pd >= pend) return pd - pstart;
*pd = a >> 8; if(++pd >= pend) return pd - pstart;
*pd = a; if(++pd >= pend) return pd - pstart;
bc = a = 0;
} }
if(bc >= 8) {
*pd = a >> 16; if(++pd >= pend) return pd - pstart;
if(bc >= 16) *(pd++) = a >> 8;
}
return pd - pstart;
}

int main() {
std::string base64_string = "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8=";
unsigned char decoded_data[32] = {0};

Base64Decode(base64_string, decoded_data, sizeof(decoded_data));

for(auto b : decoded_data) {
std::cout << static_cast<unsigned>(b) << ' ';
}
std::cout << std::endl;
return 0;
}

How to decode (from base64) a python np-array and reload it in c++ as a vector of floats?

Thank @Holt for pointing out my mistake.

First, you can't save the storage space by using base64 encoding. On the contrary, it will waste your storage. For an array with 300 floats, the storage is only 300 * 4 = 1200bytes. While after you encode it, the storage will be 1600 bytes! See more about base64 here.

Second, you want to parse the bytes into a vector<float>. You need to decode the bytes if you still use the base64 encoding. I suggest you use some third-party library or try this question. Suppose you already have the decode function.

std::string base64_decode(std::string const& encoded_string); // or something like that.

You need to use reinterpret_cast to get the value.

const std::string encoded(first, b_size);
std::string decoded = base64_decode(encoded);
std::vector<float> vec(300);
for (size_t i = 0; i < decode.size() / sizeof(float); ++i) {
vec[i] = *(reinterpret_cast<const double*>(decoded.c_str()) + i);
}

Why isn't this base64 decode/encode function working properly?

Assuming you are using this code for base64, I suspect the following will work:

int x = 1;
std::string data = base64_encode(reinterpret_cast<unsigned char *>(&x), 4);
std::string out = base64_decode(data);
int y= *(reinterpret_cast<int*>(out.c_str()));

On whatever side is doing the decode logic, it should probably validate that out.size() == sizeof(int) before doing this conversion.

C++ base64_decode() return null

That was so annoying problem. I've tried so many algorithms and i've changed my code in so many ways.

If anyone wonders, here is my solution. my encodedString string had special-characters. (/n /r /t) Thats why i've just added some code before decoding code:

        encoded.erase(std::remove(encoded.begin(), encoded.end(), '\n'), encoded.end());
encoded.erase(std::remove(encoded.begin(), encoded.end(), '\r'), encoded.end());
encoded.erase(std::remove(encoded.begin(), encoded.end(), '\t'), encoded.end());

After that decoder worked just fine.



Related Topics



Leave a reply



Submit