📄 base64.cpp
字号:
/*****************************************************************************
*****************************************************************************
*
*
* Base64 conversion.
*
* Written by Alex Fedotov, posted at CodeGuru
* (http://codeguru.earthweb.com) with no copyright or restrictions on
* its use.
*
*****************************************************************************
****************************************************************************/
#include <vxibuildopts.h>
#if P_VXI
#include "base64.h"
#define _ASSERTE(exp) if ( !(exp) ) return -1
#define _CrtIsValidPointer(ptr, len, x) (((ptr) != 0) && ((len) > 0))
const char _b64_etbl[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','+','/'
};
const char _b64_dtbl[128] = {
0x40,0x40,0x40,0x40, 0x40,0x40,0x40,0x40, 0x40,0x40,0x40,0x40, 0x40,0x40,0x40,0x40,
0x40,0x40,0x40,0x40, 0x40,0x40,0x40,0x40, 0x40,0x40,0x40,0x40, 0x40,0x40,0x40,0x40,
0x40,0x40,0x40,0x40, 0x40,0x40,0x40,0x40, 0x40,0x40,0x40,0x3E, 0x40,0x40,0x40,0x3F,
0x34,0x35,0x36,0x37, 0x38,0x39,0x3A,0x3B, 0x3C,0x3D,0x40,0x40, 0x40,0x00,0x40,0x40,
0x40,0x00,0x01,0x02, 0x03,0x04,0x05,0x06, 0x07,0x08,0x09,0x0A, 0x0B,0x0C,0x0D,0x0E,
0x0F,0x10,0x11,0x12, 0x13,0x14,0x15,0x16, 0x17,0x18,0x19,0x40, 0x40,0x40,0x40,0x40,
0x40,0x1A,0x1B,0x1C, 0x1D,0x1E,0x1F,0x20, 0x21,0x22,0x23,0x24, 0x25,0x26,0x27,0x28,
0x29,0x2A,0x2B,0x2C, 0x2D,0x2E,0x2F,0x30, 0x31,0x32,0x33,0x40, 0x40,0x40,0x40,0x40
};
//---------------------------------------------------------------------------
// b64elen
//
// Calculates length of base64-encoded string given size of binary data.
//
// Parameters:
// cb - number of bytes of binary data
//
// Returns:
// the length of base64-encoded string not including the terminating null
// character.
//
extern "C" long
b64elen(
size_t cb
)
{
return (cb + 2) / 3 * 4;
}
//---------------------------------------------------------------------------
// b64dlen
//
// Calculates size of binary data which will be produced after decoding of
// base64-encoded string with specified length.
//
// Parameters:
// cch - length of the string, not including terminating null character
//
// Returns:
// the number of bytes of binary data.
//
extern "C" long
b64dlen(
size_t cch
)
{
return cch * 3 / 4 + (cch % 4);
}
//---------------------------------------------------------------------------
// strb64e
//
// Converts a buffer with binary data into a base64-encoded string. The
// function does not store a null character at the end of the string.
//
// Parameters:
// p - pointer to a buffer with binary data
// cb - size of the buffer in bytes
// psz - pointer to a buffer that receives encoded string
//
// Returns:
// number of characters written into the output buffer.
//
// Note:
// Required size of the output buffer can be determined as b64elen(cb).
//
extern "C" long
strb64e(
const void * p,
size_t cb,
char * psz
)
{
_ASSERTE(_CrtIsValidPointer(p, cb, 0));
_ASSERTE(_CrtIsValidPointer(psz, b64elen(cb), 1));
int i;
int rem = cb % 3;
int cbr = cb - rem;
_ASSERTE((cbr % 3) == 0);
char * qsz = psz;
const char * pb = (const char *)p;
register int dw;
// convert each three consequent bytes into four base64 characters
for (i = 0; i < cbr; i += 3, psz += 4)
{
dw = ((unsigned char)pb[i]) << 16;
dw |= ((unsigned char)pb[i + 1]) << 8;
dw |= ((unsigned char)pb[i + 2]);
psz[3] = _b64_etbl[dw & 0x3F]; dw >>= 6;
psz[2] = _b64_etbl[dw & 0x3F]; dw >>= 6;
psz[1] = _b64_etbl[dw & 0x3F]; dw >>= 6;
psz[0] = _b64_etbl[dw & 0x3F];
}
// 0, 1, or 2 bytes can remain at the end of the input buffer; deal
// with each of these cases separately
switch (rem)
{
case 2:
dw = ((unsigned char)pb[i]) << 8;
dw |= ((unsigned char)pb[i + 1]);
psz[3] = '=';
psz[2] = _b64_etbl[dw & 0x3F]; dw >>= 6;
psz[1] = _b64_etbl[dw & 0x3F]; dw >>= 6;
psz[0] = _b64_etbl[dw & 0x3F];
return qsz - psz + 4;
case 1:
dw = ((unsigned char)pb[i]);
psz[3] = '=';
psz[2] = '=';
psz[1] = _b64_etbl[dw & 0x3F]; dw >>= 6;
psz[0] = _b64_etbl[dw & 0x3F];
return qsz - psz + 4;
case 0:
return qsz - psz;
default:
_ASSERTE(0);
// __assume(0);
}
}
//---------------------------------------------------------------------------
// wcsb64e
//
// Converts a buffer with binary data into a base64-encoded string. The
// function does not store a null character at the end of the string.
//
// Parameters:
// p - pointer to a buffer with binary data
// cb - size of the buffer in bytes
// psz - pointer to a buffer that receives encoded string
//
// Returns:
// number of characters written into the output buffer.
//
// Note:
// Required size of the output buffer can be determined as b64elen(cb).
//
extern "C" long
wcsb64e(
const void * p,
size_t cb,
wchar_t * psz
)
{
_ASSERTE(_CrtIsValidPointer(p, cb, 0));
_ASSERTE(_CrtIsValidPointer(psz, b64elen(cb) * sizeof(wchar_t), 1));
int i;
int rem = cb % 3;
int cbr = cb - rem;
_ASSERTE((cbr % 3) == 0);
wchar_t * qsz = psz;
const char * pb = (const char *)p;
register int dw;
// convert each three consequent bytes into four base64 characters
for (i = 0; i < cbr; i += 3, psz += 4)
{
dw = ((unsigned char)pb[i]) << 16;
dw |= ((unsigned char)pb[i + 1]) << 8;
dw |= ((unsigned char)pb[i + 2]);
psz[3] = (wchar_t)_b64_etbl[dw & 0x3F]; dw >>= 6;
psz[2] = (wchar_t)_b64_etbl[dw & 0x3F]; dw >>= 6;
psz[1] = (wchar_t)_b64_etbl[dw & 0x3F]; dw >>= 6;
psz[0] = (wchar_t)_b64_etbl[dw & 0x3F];
}
// 0, 1, or 2 bytes can remain at the end of the input buffer; deal
// with each of these cases separately
switch (rem)
{
case 2:
dw = ((unsigned char)pb[i]) << 8;
dw |= ((unsigned char)pb[i + 1]);
psz[3] = L'=';
psz[2] = (wchar_t)_b64_etbl[dw & 0x3F]; dw >>= 6;
psz[1] = (wchar_t)_b64_etbl[dw & 0x3F]; dw >>= 6;
psz[0] = (wchar_t)_b64_etbl[dw & 0x3F];
return qsz - psz + 4;
case 1:
dw = ((unsigned char)pb[i]);
psz[3] = L'=';
psz[2] = L'=';
psz[1] = (wchar_t)_b64_etbl[dw & 0x3F]; dw >>= 6;
psz[0] = (wchar_t)_b64_etbl[dw & 0x3F];
return qsz - psz + 4;
case 0:
return qsz - psz;
default:
_ASSERTE(0);
// __assume(0);
}
}
//---------------------------------------------------------------------------
// strb64d
//
// Converts a base64-encoded string into binary data. If the input string
// contains characters that are not allowed for base64, the contents of the
// output buffer is unpredictable.
//
// Parameters:
// psz - pointer to a base64-encoded sting
// cch - number of characters in the string
// p - pointer to a buffer that receives binary data
//
// Returns:
// number of bytes stored into the output buffer.
//
// Note:
// Required size of the output buffer can be determined as b64dlen(cch).
//
extern "C" long
strb64d(
const char * psz,
size_t cch,
void * p
)
{
_ASSERTE(_CrtIsValidPointer(psz, cch, 0));
_ASSERTE(_CrtIsValidPointer(p, b64dlen(cch), 1));
int i;
// ignore '=' characters that might appear at the end of the string
while (cch > 0 && psz[cch - 1] == '=')
cch--;
int rem = cch & 3;
int cch4 = cch - rem;
char * pb = (char *)p;
register int dw;
// convert each four consequtive base64 characters into three bytes
// of binary data
for (i = 0; i < cch4; i += 4, pb += 3)
{
dw = _b64_dtbl[0x7F & psz[i]] << 18;
dw |= _b64_dtbl[0x7F & psz[i + 1]] << 12;
dw |= _b64_dtbl[0x7F & psz[i + 2]] << 6;
dw |= _b64_dtbl[0x7F & psz[i + 3]];
pb[2] = (unsigned char)dw; dw >>= 8;
pb[1] = (unsigned char)dw; dw >>= 8;
pb[0] = (unsigned char)dw;
}
// a few characters might remain at the end of the string
switch (rem)
{
case 3:
dw = _b64_dtbl[0x7F & psz[i]] << 12;
dw |= _b64_dtbl[0x7F & psz[i + 1]] << 6;
dw |= _b64_dtbl[0x7F & psz[i + 2]];
//pb[2] = (unsigned char)dw; dw >>= 8;
pb[1] = (unsigned char)dw; dw >>= 8;
pb[0] = (unsigned char)dw;
return pb - (char *)p + 2;
case 2:
dw = _b64_dtbl[0x7F & psz[i]] << 6;
dw |= _b64_dtbl[0x7F & psz[i + 1]];
//pb[1] = (unsigned char)dw; dw >>= 8;
pb[0] = (unsigned char)dw;
return pb - (char *)p + 1;
case 1:
//pb[0] = _b64_dtbl[0x7F & psz[i]];
return pb - (char *)p;
case 0:
return pb - (char *)p;
default:
_ASSERTE(0);
// __assume(0);
}
}
//---------------------------------------------------------------------------
// wcsb64d
//
// Converts a base64-encoded string into binary data. If the input string
// contains characters that are not allowed for base64, the contents of the
// output buffer is unpredictable.
//
// Parameters:
// psz - pointer to a base64-encoded sting
// cch - number of characters in the string
// p - pointer to a buffer that receives binary data
//
// Returns:
// number of bytes written into the output buffer.
//
// Note:
// Required size of the output buffer can be determined as b64dlen(cch).
//
extern "C" long
wcsb64d(
const wchar_t * psz,
size_t cch,
void * p
)
{
_ASSERTE(_CrtIsValidPointer(psz, cch * sizeof(wchar_t), 0));
_ASSERTE(_CrtIsValidPointer(p, b64dlen(cch), 1));
int i;
// ignore '=' characters that might appear at the end of the string
while (cch > 0 && psz[cch - 1] == L'=')
cch--;
int rem = cch & 3;
int cch4 = cch - rem;
char * pb = (char *)p;
register int dw;
// convert each four consequtive base64 characters into three bytes
// of binary data
for (i = 0; i < cch4; i += 4, pb += 3)
{
dw = _b64_dtbl[0x7F & psz[i]] << 18;
dw |= _b64_dtbl[0x7F & psz[i + 1]] << 12;
dw |= _b64_dtbl[0x7F & psz[i + 2]] << 6;
dw |= _b64_dtbl[0x7F & psz[i + 3]];
pb[2] = (unsigned char)dw; dw >>= 8;
pb[1] = (unsigned char)dw; dw >>= 8;
pb[0] = (unsigned char)dw;
}
// a few characters might remain at the end of the string
switch (rem)
{
case 3:
dw = _b64_dtbl[0x7F & psz[i]] << 12;
dw |= _b64_dtbl[0x7F & psz[i + 1]] << 6;
dw |= _b64_dtbl[0x7F & psz[i + 2]];
//pb[2] = (unsigned char)dw; dw >>= 8;
pb[1] = (unsigned char)dw; dw >>= 8;
pb[0] = (unsigned char)dw;
return pb - (char *)p + 2;
case 2:
dw = _b64_dtbl[0x7F & psz[i]] << 6;
dw |= _b64_dtbl[0x7F & psz[i + 1]];
//pb[1] = (unsigned char)dw; dw >>= 8;
pb[0] = (unsigned char)dw;
return pb - (char *)p + 1;
case 1:
//pb[0] = _b64_dtbl[0x7F & psz[i]];
return pb - (char *)p;
case 0:
return pb - (char *)p;
default:
_ASSERTE(0);
// __assume(0);
}
}
//---------------------------------------------------------------------------
// strisb64
//
// Determines whether a string is a valid base64-encoded string.
//
// Parameters:
// psz - pointer to a string
// cch - number of characters in the string
//
// Returns:
// nonzero, if the string entirely consists of valid base64 characters,
// zero - otherwise.
//
extern "C" int
strisb64(
const char * psz,
size_t cch
)
{
_ASSERTE(_CrtIsValidPointer(psz, cch * sizeof(char), 0));
size_t i;
for (i = 0; (i < cch) && (psz[i] != '='); i++)
{
if ((psz[i] & 0x80) != 0)
return 0;
if (_b64_dtbl[psz[i]] == 0x40)
return 0;
}
if (i == cch)
return 1;
if ((cch % 4) != 0)
return 0;
switch (cch - i)
{
case 2:
if (psz[i + 1] != '=')
return 0;
case 1:
case 0:
break;
default:
return 0;
}
return 1;
}
//---------------------------------------------------------------------------
// wcsisb64
//
// Determines whether a string is a valid base64-encoded string.
//
// Parameters:
// psz - pointer to a string
// cch - number of characters in the string
//
// Returns:
// nonzero, if the string entirely consists of valid base64 characters,
// zero - otherwise.
//
extern "C" int
wcsisb64(
const wchar_t * psz,
size_t cch
)
{
_ASSERTE(_CrtIsValidPointer(psz, cch * sizeof(wchar_t), 0));
size_t i;
for (i = 0; (i < cch) && (psz[i] != L'='); i++)
{
if ((psz[i] & 0xFF80) != 0)
return 0;
if (_b64_dtbl[psz[i]] == 0x40)
return 0;
}
if (i == cch)
return 1;
if ((cch % 4) != 0)
return 0;
switch (cch - i)
{
case 2:
if (psz[i + 1] != L'=')
return 0;
case 1:
case 0:
break;
default:
return 0;
}
return 1;
}
#endif //P_VXI
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -