Хотелось бы увидеть. работоспособную реализацтю алгоритма.
void Base64_decode(
IN const CHAR* strIn, // Вход
OUT CString& strOut // Выход
) {
const static CHAR base64ABC[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
strOut.Empty();
const size_t len = strlen(strIn);
for (int i=0; i<len; i+=4) {
LONG l =
(( (strIn[i ] != '=')) ? (((LONG)(strchr(base64ABC, strIn[i ]) — base64ABC)) << 18) : 0) |
((((i+1) < len) && (strIn[i+1] != '=')) ? (((LONG)(strchr(base64ABC, strIn[i+1]) — base64ABC)) << 12) : 0) |
((((i+2) < len) && (strIn[i+2] != '=')) ? (((LONG)(strchr(base64ABC, strIn[i+2]) — base64ABC)) << 6 ) : 0) |
((((i+3) < len) && (strIn[i+3] != '=')) ? ((LONG)(strchr(base64ABC, strIn[i+3]) — base64ABC)) : 0);
BYTE ch1 = ((l>>16) & 0xFF); if (ch1) strOut += ch1;
BYTE ch2 = ((l>>8 ) & 0xFF); if (ch2) strOut += ch2;
BYTE ch3 = ( l & 0xFF); if (ch3) strOut += ch3;
}
}
Этот у меня отказался раскодировать такую строку
CString EncodedString = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
на выходе была пустая сктрока. Помогите плиз а то у меня голова уже пухнет от поисков.
04.10.04 06:41: Перенесено модератором из 'C/C++' — Павел Кузнецов
18.10.04 02:58: Перенесено модератором из 'Прочее' — Павел Кузнецов
Здравствуйте, SmokerMan, Вы писали:
SM>Хотелось бы увидеть. работоспособную реализацтю алгоритма.
Пользуюсь этим:
static char base64tab[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz0123456789+/";
char base64idx[128] =
{
'\377','\377','\377','\377','\377','\377','\377','\377',
'\377','\377','\377','\377','\377','\377','\377','\377',
'\377','\377','\377','\377','\377','\377','\377','\377',
'\377','\377','\377','\377','\377','\377','\377','\377',
'\377','\377','\377','\377','\377','\377','\377','\377',
'\377','\377','\377', 62,'\377','\377','\377', 63,
52, 53, 54, 55, 56, 57, 58, 59,
60, 61,'\377','\377','\377','\377','\377','\377',
'\377', 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,'\377','\377','\377','\377','\377',
'\377', 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,'\377','\377','\377','\377','\377'
};
#define isbase64(a) ( ('A' <= (a) && (a) <= 'Z') \
|| ('a' <= (a) && (a) <= 'z') \
|| ('0' <= (a) && (a) <= '9') \
|| (a) == '+' || (a) == '/' )
/*Декодер из Base64.
На вход:
aIn - входной буффер
aInLen - его длина
aOut - выходной буффер
aOutSize - его длина (берется из Base64GetDecodeStrLen)
aОutLen - сюда поместится длина закодированной строки
На выходе:
0 - нормальное завершение
-1 - ошибка.
*/
int Base64Decode(const char* aIn, unsigned int aInLen, char* aOut,
unsigned int aOutSize, unsigned int* aOutLen)
{
unsigned int inLen = aInLen;
char* out = aOut;
unsigned int outSize;
int isErr = 0;
int isEndSeen = 0;
int b1, b2, b3;
int a1, a2, a3, a4;
unsigned int inPos = 0;
unsigned int outPos = 0;
if (!aIn || !aOut || !aOutLen)
return -1;
outSize = (inLen/4+1)*3+1;
if (aOutSize < outSize)
return -1;
while (inPos < inLen)
{
a1 = a2 = a3 = a4 = 0;
while (inPos < inLen)
{
a1 = aIn[inPos++] & 0xFF;
if (isbase64(a1))
{
break;
}
else if (a1 == '=')
{
isEndSeen = 1;
break;
}
else if (a1 != '\r' && a1 != '\n' && a1 != ' ' && a1 != '\t')
{
isErr = 1;
}
}
while (inPos < inLen)
{
a2 = aIn[inPos++] & 0xFF;
if (isbase64(a2))
{
break;
}
else if (a2 == '=')
{
isEndSeen = 1;
break;
}
else if (a2 != '\r' && a2 != '\n' && a2 != ' ' && a2 != '\t')
{
isErr = 1;
}
}
while (inPos < inLen)
{
a3 = aIn[inPos++] & 0xFF;
if (isbase64(a3))
{
break;
}
else if (a3 == '=')
{
isEndSeen = 1;
break;
}
else if (a3 != '\r' && a3 != '\n' && a3 != ' ' && a3 != '\t')
{
isErr = 1;
}
}
while (inPos < inLen)
{
a4 = aIn[inPos++] & 0xFF;
if (isbase64(a4))
{
break;
}
else if (a4 == '=')
{
isEndSeen = 1;
break;
}
else if (a4 != '\r' && a4 != '\n' && a4 != ' ' && a4 != '\t')
{
isErr = 1;
}
}
if (isbase64(a1) && isbase64(a2) && isbase64(a3) && isbase64(a4))
{
a1 = base64idx[a1] & 0xFF;
a2 = base64idx[a2] & 0xFF;
a3 = base64idx[a3] & 0xFF;
a4 = base64idx[a4] & 0xFF;
b1 = ((a1 << 2) & 0xFC) | ((a2 >> 4) & 0x03);
b2 = ((a2 << 4) & 0xF0) | ((a3 >> 2) & 0x0F);
b3 = ((a3 << 6) & 0xC0) | ( a4 & 0x3F);
out[outPos++] = (char)b1;
out[outPos++] = (char)b2;
out[outPos++] = (char)b3;
}
else if (isbase64(a1) && isbase64(a2) && isbase64(a3) && a4 == '=')
{
a1 = base64idx[a1] & 0xFF;
a2 = base64idx[a2] & 0xFF;
a3 = base64idx[a3] & 0xFF;
b1 = ((a1 << 2) & 0xFC) | ((a2 >> 4) & 0x03);
b2 = ((a2 << 4) & 0xF0) | ((a3 >> 2) & 0x0F);
out[outPos++] = (char)b1;
out[outPos++] = (char)b2;
break;
}
else if (isbase64(a1) && isbase64(a2) && a3 == '=' && a4 == '=')
{
a1 = base64idx[a1] & 0xFF;
a2 = base64idx[a2] & 0xFF;
b1 = ((a1 << 2) & 0xFC) | ((a2 >> 4) & 0x03);
out[outPos++] = (char)b1;
break;
}
else
{
break;
}
if (isEndSeen)
{
break;
}
} // end while loop
*aOutLen = outPos;
return (isErr) ? -1 : 0;
}
int Base64GetDecodeStrLen( int iEncodeStrLen)
{
return (iEncodeStrLen/4+1)*3+1;
}
Здравствуйте, SmokerMan, Вы писали:
SM>Хотелось бы увидеть. работоспособную реализацтю алгоритма.
Не знаю насколько работающее, но взято из одной линуксовой проги.
/*
** Author: Daniel Stenberg <Daniel.Stenberg@haxx.nu>
** Version: 0.1
**
** This is a Base64 encoder as defined in RFC 2045. If the output is gonna be
** used in a mail body: "The encoded output stream must be represented in
** lines of no more than 76 characters each."
**
** CHANGES by Daniel Stenberg. May 11, 1998:
**
** - Encoded strings that ended with more than one = caused the decode
** function+ to generate 3 extra zero bytes at the end of the output.
*/
#include "hypermail.h"
#include "base64.h"
void base64Decode(char *intext, char *out, int *length)
{
unsigned char ibuf[4];
unsigned char obuf[3];
char ignore;
char endtext = FALSE;
char ch;
int lindex = 0;
*length = 0;
memset(ibuf, 0, sizeof(ibuf));
while (*intext) {
ch = *intext;
ignore = FALSE;
if ((ch >= 'A') && (ch <= 'Z'))
ch = ch - 'A';
else if ((ch >= 'a') && (ch <= 'z'))
ch = ch - 'a' + 26;
else if ((ch >= '0') && (ch <= '9'))
ch = ch - '0' + 52;
else if (ch == '+')
ch = 62;
else if (ch == '=') { /* end of text */
if (endtext)
break;
endtext = TRUE;
lindex--;
if (lindex < 0)
lindex = 3;
}
else if (ch == '/')
ch = 63;
else if (endtext)
break;
else
ignore = TRUE;
if (!ignore) {
if (!endtext) {
ibuf[lindex] = ch;
lindex++;
lindex &= 3; /* use bit arithmetic instead of remainder */
}
if ((0 == lindex) || endtext) {
obuf[0] = (ibuf[0] << 2) | ((ibuf[1] & 0x30) >> 4);
obuf[1] =
((ibuf[1] & 0x0F) << 4) | ((ibuf[2] & 0x3C) >> 2);
obuf[2] = ((ibuf[2] & 0x03) << 6) | (ibuf[3] & 0x3F);
switch (lindex) {
case 1:
sprintf(out, "%c", obuf[0]);
out++;
(*length)++;
break;
case 2:
sprintf(out, "%c%c", obuf[0], obuf[1]);
out += 2;
(*length) += 2;
break;
default:
sprintf(out, "%c%c%c", obuf[0], obuf[1], obuf[2]);
out += 3;
(*length) += 3;
break;
}
memset(ibuf, 0, sizeof(ibuf));
}
}
intext++;
}
*out = 0;
}
... << RSDN@Home 1.1.4 beta 3 rev. 0>>