www.pudn.com > base64.zip > base64.c, change:2012-03-02,size:4806b


#include "base64.h"

#include <stdio.h>
#include <string.h>
#include <stdlib.h>


int base64_encode (const char *str, int length, char *b64store, int b64len)
{
  /* Conversion table.  */
  static char tbl[64] = {
    'A','B','C','D','E','F','G','H',
    'I','J','K','L','M','N','O','P',
    'Q','R','S','T','U','V','W','X',
    'Y','Z','a','b','c','d','e','f',
    'g','h','i','j','k','l','m','n',
    'o','p','q','r','s','t','u','v',
    'w','x','y','z','0','1','2','3',
    '4','5','6','7','8','9','+','/'
  };
  int i, pos, k;
  pos = length - length % 3;
  const unsigned char *s = (const unsigned char *) str;
  char *p = b64store;

  /* Transform the 3x8 bits to 4x6 bits, as required by base64.  */
  //这里有一个问题,length % 3 != 0 出错
  for (i = 0, k=0; i < pos && k < b64len; i += 3, ++k) {
      *p++ = tbl[s[0] >> 2];
      *p++ = tbl[((s[0] & 3) << 4) + (s[1] >> 4)];
      *p++ = tbl[((s[1] & 0xf) << 2) + (s[2] >> 6)];
      *p++ = tbl[s[2] & 0x3f];
      s += 3;
  }

  /* 一个字符转2个字节 */
  if (length % 3 == 1 && k + 3 < b64len){
    *p++ = tbl[s[0] >>2];
    *p++ = tbl[((s[0] & 3) <<4)];
    *p++ = '=';
    *p++ = '=';
  }else if (length % 3 == 2 && k + 3 < b64len) {
    *p++ = tbl[s[0] >>2];
    *p++ = tbl[((s[0] & 3) <<4) + (s[1] >> 4)];
    *p++ = tbl[((s[1] & 0xf) << 2)];
    *p++ = '=';
  }

  *p = '\0';

  return p - b64store;
}

#define IS_ASCII(c) (((c) & 0x80) == 0)
#define IS_BASE64(c) ((IS_ASCII (c) && base64_char_to_value[c] >= 0) || c == '=')

#define NEXT_BASE64_CHAR(c, p) do {			\
  c = *p++;						\
} while (c != '\0' && !IS_BASE64 (c))


//返回解码后的字节数
int base64_decode (const char *base64, char *to)
{
    static short base64_char_to_value[128] =
    {
      -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,	/*   0-  9 */
      -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,	/*  10- 19 */
      -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,	/*  20- 29 */
      -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,	/*  30- 39 */
      -1,  -1,  -1,  62,  -1,  -1,  -1,  63,  52,  53,	/*  40- 49 */
      54,  55,  56,  57,  58,  59,  60,  61,  -1,  -1,	/*  50- 59 */
      -1,  -1,  -1,  -1,  -1,  0,   1,   2,   3,   4,	/*  60- 69 */
      5,   6,   7,   8,   9,   10,  11,  12,  13,  14,	/*  70- 79 */
      15,  16,  17,  18,  19,  20,  21,  22,  23,  24,	/*  80- 89 */
      25,  -1,  -1,  -1,  -1,  -1,  -1,  26,  27,  28,	/*  90- 99 */
      29,  30,  31,  32,  33,  34,  35,  36,  37,  38,	/* 100-109 */
      39,  40,  41,  42,  43,  44,  45,  46,  47,  48,	/* 110-119 */
      49,  50,  51,  -1,  -1,  -1,  -1,  -1		/* 120-127 */
    };

  const char *p = base64;
  char *q = to;

    while (1)
    {
      unsigned char c;
      unsigned long value;

      /* Process first byte of a quadruplet.  */
      NEXT_BASE64_CHAR (c, p);
      if (!c)
	break;
      if (c == '=')
	return -1;		/* illegal '=' while decoding base64 */
      value = base64_char_to_value[c] << 18;

      /* Process scond byte of a quadruplet.  */
      NEXT_BASE64_CHAR (c, p);
      if (!c)
	return -1;		/* premature EOF while decoding base64 */
      if (c == '=')
	return -1;		/* illegal `=' while decoding base64 */
      value |= base64_char_to_value[c] << 12;
      *q++ = value >> 16;

      /* Process third byte of a quadruplet.  */
      NEXT_BASE64_CHAR (c, p);
      if (!c)
	return -1;		/* premature EOF while decoding base64 */

      if (c == '=')
	{
	  NEXT_BASE64_CHAR (c, p);
	  if (!c)
	    return -1;		/* premature EOF while decoding base64 */
	  if (c != '=')
	    return -1;		/* padding `=' expected but not found */
	  continue;
	}

      value |= base64_char_to_value[c] << 6;
      *q++ = 0xff & value >> 8;

      /* Process fourth byte of a quadruplet.  */
      NEXT_BASE64_CHAR (c, p);
      if (!c)
	return -1;		/* premature EOF while decoding base64 */
      if (c == '=')
	continue;

      value |= base64_char_to_value[c];
      *q++ = 0xff & value;
    }

  return q - to;
}

#if 0
int main(int argc,char **argv) 
{
	short sh[3] = {1,1,1};
	short sdest = sh[0] << 18;
	unsigned int ldest = sh[0] << 18;
	printf("sdest=0x%08x,ldest=0x%08x\n",sdest,ldest);
	
	char ch[4] = {1,0x11,0x81,1};
	ldest = ch[1] >> 1;
	printf("ldest=0x%08x\n",ldest);
	ldest = ch[2] >> 1;
	printf("ldest=0x%08x\n",ldest);
	char cdest = ch[2] >> 1;
	printf("cdest=%d\n",cdest);
	
	
	const char *test_str = "hello34511qqww";
	int b64_len = strlen(test_str)/3*4+5;
	char *b64_str = malloc(b64_len);
	
	b64_len = base64_encode(test_str,strlen(test_str),b64_str,b64_len);
	printf("base64_encode result = [%s],retlen =%d\n",b64_str,b64_len);
	
	/* decode*/
	char *b64_dstr = malloc(b64_len);
	int str_len = base64_decode(b64_str, b64_dstr);
	printf("base64_decode result = [%s],retlen =%d\n",b64_dstr,str_len);
	
	return 0;
}
#endif