base64编解码方法

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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值