I have binary data in an unsigned char variable. I need to convert them to PEM base64 in c. I looked in openssl library but i could not find any function. Does any body have any idea?
+5
A:
glib has functions for base64 encoding: http://library.gnome.org/devel/glib/2.18/glib-Base64-Encoding.html
stesch
2008-12-04 23:11:27
+4
A:
But you can also do it in openssl (openssl enc
command does it....), look at the BIO_f_base64()
function
Piotr Lesnicki
2008-12-04 23:28:26
It seems like the OP is already using OpenSSL for some other reason, so this is probably the best way to go about it.
Josh K
2009-04-30 18:19:32
+4
A:
GNU coreutils has it in lib/base64. It's a little bloated but deals with stuff like EBCDIC. You can also play around on your own, e.g.,
char base64_digit (n) unsigned n; {
if (n < 10) return n - '0';
else if (n < 10 + 26) return n - 'a';
else if (n < 10 + 26 + 26) return n - 'A';
else assert(0);
return 0;
}
unsigned char base64_decode_digit(char c) {
switch (c) {
case '=' : return 62;
case '.' : return 63;
default :
if (isdigit(c)) return c - '0';
else if (islower(c)) return c - 'a' + 10;
else if (isupper(c)) return c - 'A' + 10 + 26;
else assert(0);
}
return 0xff;
}
unsigned base64_decode(char *s) {
char *p;
unsigned n = 0;
for (p = s; *p; p++)
n = 64 * n + base64_decode_digit(*p);
return n;
}
Norman Ramsey
2008-12-05 02:37:53
+1
A:
Here's the decoder I've been using for years...
static const char table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
static const int BASE64_INPUT_SIZE = 57;
BOOL isbase64(char c)
{
return c && strchr(table, c) != NULL;
}
inline char value(char c)
{
const char *p = strchr(table, c);
if(p) {
return p-table;
} else {
return 0;
}
}
int UnBase64(unsigned char *dest, const unsigned char *src, int srclen)
{
*dest = 0;
if(*src == 0)
{
return 0;
}
unsigned char *p = dest;
do
{
char a = value(src[0]);
char b = value(src[1]);
char c = value(src[2]);
char d = value(src[3]);
*p++ = (a << 2) | (b >> 4);
*p++ = (b << 4) | (c >> 2);
*p++ = (c << 6) | d;
if(!isbase64(src[1]))
{
p -= 2;
break;
}
else if(!isbase64(src[2]))
{
p -= 2;
break;
}
else if(!isbase64(src[3]))
{
p--;
break;
}
src += 4;
while(*src && (*src == 13 || *src == 10)) src++;
}
while(srclen-= 4);
*p = 0;
return p-dest;
}
LarryF
2009-01-08 23:31:19
It's just a very simple operation that makes sure the dest buffer is set to NULL in case the caller did not do that before the call, and if perhaps the decode failed, the returned buffer would be zero length. I didn't say I debugged, traced, and profiled this routine, it's just one I've been using for years. :) When I look at it now, it really doesn’t need to be there, so, why don't we call it an "exercise for the reader?" hehe.. Maybe I'll just edit it out. Thanks for pointing it out!
LarryF
2009-11-24 03:34:03
@LarryF, your `UnBase64` function may compromise the memory after the dest buffer, if that buffer is the exact size required to decode the base 64 encoded string. Take for instance the simple case where you try to decode the following base 64 encoded string "BQ==", into a single BYTE i.e. `unsigned char Result = 0; UnBase64(` It will corrupt the stack!
Miky Dinescu
2010-05-08 21:14:29
A:
Larry - could you explain what the "value" function is in your UnBase64 code sample? A C lib function I hope?
Thanks! :)
Craig
2009-11-10 17:08:01
Sorry Craig.. I just noticed this, and posted the correct function in the actual post. It's an inline function that just verifies that char passed is actually in the b64 table of chars... Good catch, and my apologies for missing it...
LarryF
2009-11-24 03:42:13