📄 base64.c
字号:
/****************************************************************************
*
* Copyright (c) 1998, Network Associates, Inc. and its affiliated Companies
*
****************************************************************************/
#include "tc.h"
#if PGP_MACINTOSH
#include <unix.h>
#else
#include <sys/types.h>
#endif
#ifdef TESTING
#include <stdio.h>
#endif /* TESTING */
#include "cms_proto.h"
static const unsigned char BaseChars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
#define BaseChar(c) BaseChars[c]
static const unsigned char BaseVals[] = {
0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,62, 0xff,0xff,0xff,63,
52,53,54,55, 56,57,58,59, 60,61,0xff,0xff, 0xff,0xff,0xff,0xff,
0xff, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11,12,13,14,
15,16,17,18, 19,20,21,22, 23,24,25,0xff, 0xff,0xff,0xff,0xff,
0xff,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40,
41,42,43,44, 45,46,47,48, 49,50,51,0xff, 0xff,0xff,0xff,0xff
};
#define BaseVal(c) BaseVals[c]
int tc_encode_base64 (unsigned char **out, size_t *outlen,
const unsigned char *in, size_t inlen,
TC_CONTEXT *ctx)
{
unsigned char *curpos;
unsigned char a, b, c;
/* determine how long the output will be. if it is not a multple of 3
* bytes, increase length so that it is so that the pad characters are
* accounted for.
*/
if (inlen % 3 != 0)
*outlen = inlen + 3 - inlen % 3;
else
*outlen = inlen;
/* base64 encoding creates 4 output chars for every 3 input chars */
*outlen = 4 * (*outlen) / 3;
if ((*out = TC_Alloc(ctx->memMgr, *outlen + 1)) == NULL)
return TC_E_NOMEMORY;
curpos = *out;
while (inlen)
{
a = *in++;
inlen--;
*curpos++ = BaseChar (a >> 2);
if (inlen)
b = *in++;
else
b = 0;
*curpos++ = BaseChar (((a & 0x03) << 4) | (b >> 4));
if (!inlen)
{
*curpos++ = '=';
*curpos++ = '=';
break;
}
inlen--;
if (inlen)
c = *in++;
else
c = 0;
*curpos++ = BaseChar (((b & 0x0f) << 2) | (c >> 6));
if (!inlen)
{
*curpos++ = '=';
break;
}
inlen--;
*curpos++ = BaseChar (c & 0x3f);
}
*curpos = 0;
return 0;
}
int
tc_decode_base64 (unsigned char **out,
size_t *outlen,
const unsigned char *in,
TC_CONTEXT *ctx)
{
unsigned char *curpos;
unsigned char a, b;
*outlen = (3 * strlen ((char *) in)) / 4; /* maximum length */
if ((*out = TC_Alloc(ctx->memMgr, *outlen)) == NULL)
return TC_E_NOMEMORY;
curpos = *out;
SKIPWS (in);
while (*in)
{
a = *in++;
SKIPWS (in);
if (!*in)
return (TC_E_PARSE);
b = *in++;
SKIPWS (in);
if (!*in)
return (TC_E_PARSE);
*curpos++ = (BaseVal (a) << 2) | (BaseVal (b) >> 4);
a = b;
b = *in++;
SKIPWS (in);
if (!*in)
return (TC_E_PARSE);
if (b == '=')
break;
*curpos++ = (BaseVal (a) << 4) | (BaseVal (b) >> 2);
a = b;
b = *in++;
SKIPWS (in);
if (b == '=')
break;
*curpos++ = (BaseVal (a) << 6) | BaseVal (b);
}
*outlen = curpos - *out; /* real length */
return 0;
}
/* NOTE: this has NOT been updated to use mem. mgmt changes */
#ifdef TESTING
int main()
{
unsigned char input[1024];
unsigned char *enc;
unsigned char *dec;
size_t enclen;
size_t declen;
fgets ((char *) input, sizeof (input), stdin);
tc_encode_base64 (&enc, &enclen, input, strlen ((char *) input));
puts ((char *) enc);
if (strlen (enc) != enclen)
{
puts ("length is bad.");
exit (0);
}
if (tc_decode_base64 (&dec, &declen, enc) != 0)
{
puts ("base64 decode failed.");
exit (0);
}
dec[declen] = 0;
puts ((char *) dec);
if (strcmp ((char *) dec, (char *) input) == 0)
puts ("success.");
else
puts ("failed.");
free (enc);
free (dec);
exit (0);
}
#endif /* TESTING */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -