base64编码方法:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef enum { FALSE = 0, TRUE = 1 } boolean_t;
static const char base64[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
/*
* State of a base64 decoding process in progress.
*/
typedef struct
{
int length; /* Desired length of binary data or -1 */
int digits; /* Number of buffered base64 digits */
boolean_t seen_end; /* True if "=" end marker seen */
int val[4];
char *dst; /* Head of the available space for resulting
* binary data */
char *dstend; /* End of the buffer */
} base64_decode_ctx_t;
static int mem_tobuffer(base64_decode_ctx_t *ctx, void *base, unsigned int length)
{
if (ctx->dst + length >= ctx->dstend)
return (-1);
memcpy(ctx->dst, base, length);
ctx->dst += length;
return (0);
}
static inline void base64_decode_init(base64_decode_ctx_t *ctx, int length,
char *result, size_t resultlen)
{
ctx->digits = 0;
ctx->seen_end = FALSE;
ctx->length = length;
ctx->dst = result;
ctx->dstend = result + resultlen;
}
static inline int base64_decode_char(base64_decode_ctx_t *ctx, int c)
{
char *s;
if (ctx->seen_end == TRUE)
return (-1);
if ((s = strchr(base64, c)) == NULL)
return (-1);
ctx->val[ctx->digits++] = s - base64;
if (ctx->digits == 4)
{
int n;
unsigned char buf[3];
if (ctx->val[0] == 64 || ctx->val[1] == 64)
return (-1);
if (ctx->val[2] == 64 && ctx->val[3] != 64)
return (-1);
/*
* Check that bits that should be zero are.
*/
if (ctx->val[2] == 64 && (ctx->val[1] & 0xf) != 0)
return (-1);
/*
* We don't need to test for ctx->val[2] != 64 as
* the bottom two bits of 64 are zero.
*/
if (ctx->val[3] == 64 && (ctx->val[2] & 0x3) != 0)
return (-1);
n = (ctx->val[2] == 64) ? 1 :
(ctx->val[3] == 64) ? 2 : 3;
if (n != 3)
{
ctx->seen_end = TRUE;
if (ctx->val[2] == 64)
ctx->val[2] = 0;
if (ctx->val[3] == 64)
ctx->val[3] = 0;
}
buf[0] = (ctx->val[0] << 2) | (ctx->val[1] >> 4);
buf[1] = (ctx->val[1] << 4) | (ctx->val[2] >> 2);
buf[2] = (ctx->val[2] << 6) | (ctx->val[3]);
if (mem_tobuffer(ctx, buf, n))
return (-1);
if (ctx->length >= 0)
{
if (n > ctx->length)
return (-1);
else
ctx->length -= n;
}
ctx->digits = 0;
}
return (0);
}
static inline int base64_decode_finish(base64_decode_ctx_t *ctx)
{
if (ctx->length > 0)
return (-1);
if (ctx->digits != 0)
return (-1);
return (0);
}
int base64_decodestring(const char *cstr, char *result, size_t resultlen)
{
base64_decode_ctx_t ctx;
base64_decode_init(&ctx, -1, result, resultlen);
for (;;)
{
int c = *cstr++;
if (c == '\0')
break;
if (c == ' ' || c == '\t' || c == '\n' || c == '\r')
continue;
if (base64_decode_char(&ctx, c))
return (-1);
}
if (base64_decode_finish(&ctx))
return (-1);
return (ctx.dst - result);
}
int base64_encode(unsigned char *buf, const unsigned char*text, int size)
{
char *base64_encoding = base64;
int buflen = 0;
while (size > 0)
{
*buf++ = base64_encoding[(text[0] >> 2) & 0x3f];
if (size > 2)
{
*buf++ = base64_encoding[((text[0] & 3) << 4) | (text[1] >> 4)];
*buf++ = base64_encoding[((text[1] & 0xF) << 2) | (text[2] >> 6)];
*buf++ = base64_encoding[text[2] & 0x3F];
}
else
{
switch (size)
{
case 1:
*buf++ = base64_encoding[(text[0] & 3) << 4 ];
*buf++ = '=';
*buf++ = '=';
break;
case 2:
*buf++ = base64_encoding[((text[0] & 3) << 4) | (text[1] >> 4)];
*buf++ = base64_encoding[((text[1] & 0x0F) << 2) | (text[2] >> 6)];
*buf++ = '=';
break;
}
}
text += 3;
size -= 3;
buflen += 4;
}
*buf = 0;
return buflen;
}
int main()
{
char destr[64] = {0};
size_t len = 64;
unsigned char buf[64] = {0};
memset(buf, 0, sizeof(buf));
base64_encode(buf, "GET_SN_INFO", strlen("GET_SN_INFO"));
printf("buf=[%s]\n", buf);
base64_decodestring(buf, destr, len);
printf("destr=[%s]\n", destr);
return 0;
}