怎么实现用BASE64编解码?谢谢

f26511314 2002-10-22 05:06:58
怎么实现用BASE64编解码?
...全文
102 23 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
23 条回复
切换为时间正序
请发表友善的回复…
发表回复
playguy 2003-03-02
  • 打赏
  • 举报
回复
可以去这里看一看,有完整的演示代码,绝对实用:
http://www.aslike.net
ttapi 2002-10-24
  • 打赏
  • 举报
回复
居然忘记给出两个表了 :( sorry
const unsigned char CPBase64Decoder::m_table[] = {
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, // 0-15
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, // 16-31
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 62, 255, 255, 255, 63, // 32-47
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255, 255, 64, 255, 255, // 48-63
255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, // 64-79
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 255, // 80-95
255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, // 96-111
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 255, 255, 255, 255, 255, // 112-127
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255
};

const char* CPBase64Encoder::m_table =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
ttapi 2002-10-24
  • 打赏
  • 举报
回复
hi.
用联合也是可以的。但这是我很久以前写的代码,现在也不想改了。
至少他的工作是正常的。当时的考虑好像是说用移位操作比变体结构
执行起来来得快一点。
原理其实很简单,我想大家都会。

使用方法是:
Encoder: 输入一个二进制buffer, 长度为length,
返回值在m_strEncoded 里面。这是一个 string 型的变量
Decoder: 输入一个 string 类型的编码数据, 输出放在 m_buf 里面
m_buf 管理一个二进制 buffer.
f26511314 2002-10-24
  • 打赏
  • 举报
回复
我把 unsigned char Input[3];
改成 unsigned char Input[100];
可以了吧
f26511314 2002-10-23
  • 打赏
  • 举报
回复
to :bendou16(跳动的心)
我用了你的代码,调试的时候怎么有问题呢

CString str="1223454";
_in=str;
encode64(_in, sizeof(_in),_out, 20, (unsigned*)(sizeof(_out)));

执行到if (outlen)
*outlen = olen;时候
弹出对话框提示:Unhandled exception in SendMail.exe:0xC0000005 :Access Violtiona

2ndboy 2002-10-23
  • 打赏
  • 举报
回复
typedef union
{
unsigned char Input[3];

struct
{
unsigned I2h2:2;
unsigned I1 :6;
unsigned I3h4:4;
unsigned I2l4:4;
unsigned I4 :6;
unsigned I3l2:2;
} Index;
} BASE64, *PBASE64;

// BASE64 编码的码表
unsigned char g_Alphabet[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', '+', '/'
};

BOOL
Encode(
PBASE64 pBase64Input,
UINT uInputNum,
PUCHAR pOutput )
{
UINT i;

if( uInputNum == 0 )
return( FALSE );

for( i = uInputNum; i < 3; i++ )
pBase64Input->Input[i] = '\0';

pOutput[0] = g_Alphabet[ pBase64Input->Index.I1 ];
pOutput[1] = g_Alphabet[ (pBase64Input->Index.I2h2 << 4) | pBase64Input->Index.I2l4 ];
pOutput[2] = g_Alphabet[ (pBase64Input->Index.I3h4 << 2) | pBase64Input->Index.I3l2 ];
pOutput[3] = g_Alphabet[ pBase64Input->Index.I4 ];

for( i = uInputNum + 1; i < 4; i++ )
pOutput[i] = '=';

return( TRUE );
}
bendou16 2002-10-23
  • 打赏
  • 举报
回复
下面是h 和cpp文件,自己用吧,把分给我就行了
.h
#ifndef _BASE64ENC_H
#define _BASE64ENC_H




int encode64(const char *_in, unsigned inlen,
char *_out, unsigned outmax, unsigned *outlen);
int decode64(const char *in, unsigned inlen, char *out, unsigned *outlen);

#endif
////////////////////////////////////////////////////////////
.cpp
#define OK (0)
#define FAIL (-1)
#define BUFOVER (-2)

#define CHAR64(c) (((c) < 0 || (c) > 127) ? -1 : index_64[(c)])








static char basis_64[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????";

static char index_64[128] = {
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,
-1, 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, -1, -1, -1, -1, -1,
-1, 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, -1, -1, -1, -1, -1
};






int encode64(const char *_in, unsigned inlen,
char *_out, unsigned outmax, unsigned *outlen)
{

const unsigned char *in = (const unsigned char *) _in;
unsigned char *out = (unsigned char *) _out;
unsigned char oval;
char *blah;
unsigned olen;

olen = (inlen + 2) / 3 * 4;
if (outlen)
*outlen = olen;
if (outmax < olen)
return BUFOVER;

blah = (char *) out;
while (inlen >= 3)
{
*out++ = basis_64[in[0] >> 2];
*out++ = basis_64[((in[0] << 4) & 0x30) | (in[1] >> 4)];
*out++ = basis_64[((in[1] << 2) & 0x3c) | (in[2] >> 6)];
*out++ = basis_64[in[2] & 0x3f];
in += 3;
inlen -= 3;
}
if (inlen > 0)
{
*out++ = basis_64[in[0] >> 2];
oval = (in[0] << 4) & 0x30;
if (inlen > 1)
oval |= in[1] >> 4;
*out++ = basis_64[oval];
*out++ = (inlen < 2) ? '=' : basis_64[(in[1] << 2) & 0x3c];
*out++ = '=';
}

if (olen < outmax)
*out = '\0';

return OK;

}




int decode64(const char *in, unsigned inlen, char *out, unsigned *outlen)
{

unsigned len = 0,
lup;
int c1,
c2,
c3,
c4;

if (in[0] == '+' && in[1] == ' ')
in += 2;

if (*in == '\0')
return FAIL;

for (lup = 0; lup < inlen / 4; lup++)
{
c1 = in[0];
if (CHAR64(c1) == -1)
return FAIL;
c2 = in[1];
if (CHAR64(c2) == -1)
return FAIL;
c3 = in[2];
if (c3 != '=' && CHAR64(c3) == -1)
return FAIL;
c4 = in[3];
if (c4 != '=' && CHAR64(c4) == -1)
return FAIL;
in += 4;
*out++ = (CHAR64(c1) << 2) | (CHAR64(c2) >> 4);
++len;
if (c3 != '=')
{
*out++ = ((CHAR64(c2) << 4) & 0xf0) | (CHAR64(c3) >> 2);
++len;
if (c4 != '=')
{
*out++ = ((CHAR64(c3) << 6) & 0xc0) | CHAR64(c4);
++len;
}
}
}

*out = 0;
*outlen = len;

return OK;

}
zhouzcy 2002-10-23
  • 打赏
  • 举报
回复
能否告诉怎样转换的吗,只要过程就行了,谢谢!
f26511314 2002-10-23
  • 打赏
  • 举报
回复
to 2ndboy(丢丢)
看的我一塌糊涂,
怎样用联合来解决?
给段代码先

可以多给分
2ndboy 2002-10-23
  • 打赏
  • 举报
回复
每次只能放3个字符进去,循环一下就能转换整篇东西。
itaolu 2002-10-23
  • 打赏
  • 举报
回复
http://asp.7i24.com/netcool/laoluo/articles/show_article.asp?Article_ID=17
f26511314 2002-10-23
  • 打赏
  • 举报
回复
to :2ndboy(丢丢)
我这样把赋初值有问题吗?编译通过,执行出错!
PBASE64 pBase64Input;
strcpy(pBase64Input->Input,(char *)LPCSTR(m_user));

弹出对话框提示:Unhandled exception in SendMail.exe:0xC0000005 :Access Violtiona

2ndboy 2002-10-22
  • 打赏
  • 举报
回复
to ttapi(我爱虫虫):

怎么不用联合来解决?
realdreamer 2002-10-22
  • 打赏
  • 举报
回复
vc.net ATL 有这个算法
ttapi 2002-10-22
  • 打赏
  • 举报
回复
怎么只有20分啊?上当了 :(
ttapi 2002-10-22
  • 打赏
  • 举报
回复
很久以前写的代码, 看在 100 分的份上就给你吧。里面的小 Bug 自己改吧。

void CPBase64Encoder::Encode(const unsigned char *in, int length)
{
const char* CrLf = "\r\n";
unsigned char buf[3]; // encode in buffer, 3 bytes long
ostrstream outb; // encode output
CPBinaryInputBuffer inbuf(in, length);
int ReadNow = 0;
int BytesWriten = 0;
int CrLfCount = 0;
do
{
ReadNow = inbuf.Read(buf, 3);
if(ReadNow < 3)
{
switch(ReadNow)
{
case 1:
outb << m_table[buf[0] >> 2];
outb << m_table[(buf[0] & 0x03) << 4];
outb << '=';
outb << '=';
BytesWriten += 4;
break;
case 2:
outb << m_table[buf[0] >> 2];
outb << m_table[((buf[0] & 0x03) << 4) | (buf[1] >> 4)];
outb << m_table[(buf[1] & 0x0f) << 2];
outb << '=';
BytesWriten += 4;
break;
}

break;
}
else
{
outb << m_table[buf[0] >> 2];
outb << m_table[((buf[0] & 0x03) << 4) | (buf[1] >> 4)];
outb << m_table[((buf[1] & 0x0f) << 2) | (buf[2] >> 6)];
outb << m_table[buf[2] & 0x3f];
BytesWriten += 4;

if(BytesWriten % 76 == 0) // need a CrLf
{
outb << CrLf;
CrLfCount += 2;
}
}
}while(ReadNow >= 3);

m_strEncoded = outb.rdbuf()->str();
m_strEncoded.resize(BytesWriten + CrLfCount);
}


bool CPBase64Decoder::Decode(const string& in)
{
unsigned char buf[4];
unsigned char buf2[3];

int offset, length;

offset = 0;
length = in.size() ;

bool passed = false; // passed a '=' sign?
do
{
char c;

// discard CrLf
while((in[offset] == 0x0d) || (in[offset] == 0x0a))
{
offset++;
}

if(offset == length)
return true;

// read 4 bytes to decode buf
int validBytes = 0;
if(length - offset >= 4)
{
c = in[offset++]; buf[0] = m_table[c]; validBytes += (c=='=') ? 0:1;
c = in[offset++]; buf[1] = m_table[c]; validBytes += (c=='=') ? 0:1;
c = in[offset++]; buf[2] = m_table[c]; validBytes += (c=='=') ? 0:1;
c = in[offset++]; buf[3] = m_table[c]; validBytes += (c=='=') ? 0:1;
}
else // less than 4 bytes. error.
return false;


validBytes--;
switch(validBytes)
{
case 3:
buf2[0] = (buf[0] << 2) | ((buf[1] >> 4) & 3);
buf2[1] = (buf[1] << 4) | ((buf[2] >> 2) & 0x0f);
buf2[2] = (buf[2] << 6) | (buf[3] & 0x3f);
break;
case 2:
buf2[0] = (buf[0] << 2) | ((buf[1] >> 4) & 3);
buf2[1] = (buf[1] << 4) | ((buf[2] >> 2) & 0x0f);
buf2[2] = 0;
break;
case 1:
buf2[0] = (buf[0] << 2) | ((buf[1] >> 4) & 3);
break;
default: // encounter a decoder error
return false;
}

m_buf.write(buf2, validBytes);

if(validBytes < 3)
return true;
if(offset == length)
return true;
}while(1);
return true;
}
双杯献酒 2002-10-22
  • 打赏
  • 举报
回复
2ndboy(丢丢)说的很清楚了.
2ndboy 2002-10-22
  • 打赏
  • 举报
回复
总共就这么长,很简单,自己练练手吧
2ndboy 2002-10-22
  • 打赏
  • 举报
回复
6.8. Base64 Content-Transfer-Encoding

The Base64 Content-Transfer-Encoding is designed to represent
arbitrary sequences of octets in a form that need not be humanly
readable. The encoding and decoding algorithms are simple, but the
encoded data are consistently only about 33 percent larger than the
unencoded data. This encoding is virtually identical to the one used
in Privacy Enhanced Mail (PEM) applications, as defined in RFC 1421.

A 65-character subset of US-ASCII is used, enabling 6 bits to be
represented per printable character. (The extra 65th character, "=",
is used to signify a special processing function.)

NOTE: This subset has the important property that it is represented
identically in all versions of ISO 646, including US-ASCII, and all
characters in the subset are also represented identically in all
versions of EBCDIC. Other popular encodings, such as the encoding
used by the uuencode utility, Macintosh binhex 4.0 [RFC-1741], and
the base85 encoding specified as part of Level 2 PostScript, do not
share these properties, and thus do not fulfill the portability
requirements a binary transport encoding for mail must meet.

The encoding process represents 24-bit groups of input bits as output
strings of 4 encoded characters. Proceeding from left to right, a
24-bit input group is formed by concatenating 3 8bit input groups.
These 24 bits are then treated as 4 concatenated 6-bit groups, each
of which is translated into a single digit in the base64 alphabet.
When encoding a bit stream via the base64 encoding, the bit stream
must be presumed to be ordered with the most-significant-bit first.
That is, the first bit in the stream will be the high-order bit in
the first 8bit byte, and the eighth bit will be the low-order bit in
the first 8bit byte, and so on.

Each 6-bit group is used as an index into an array of 64 printable
characters. The character referenced by the index is placed in the
output string. These characters, identified in Table 1, below, are
selected so as to be universally representable, and the set excludes
characters with particular significance to SMTP (e.g., ".", CR, LF)
and to the multipart boundary delimiters defined in RFC 2046 (e.g.,
"-").

Table 1: The Base64 Alphabet

Value Encoding Value Encoding Value Encoding Value Encoding
0 A 17 R 34 i 51 z
1 B 18 S 35 j 52 0
2 C 19 T 36 k 53 1
3 D 20 U 37 l 54 2
4 E 21 V 38 m 55 3
5 F 22 W 39 n 56 4
6 G 23 X 40 o 57 5
7 H 24 Y 41 p 58 6
8 I 25 Z 42 q 59 7
9 J 26 a 43 r 60 8
10 K 27 b 44 s 61 9
11 L 28 c 45 t 62 +
12 M 29 d 46 u 63 /
13 N 30 e 47 v
14 O 31 f 48 w (pad) =
15 P 32 g 49 x
16 Q 33 h 50 y

The encoded output stream must be represented in lines of no more
than 76 characters each. All line breaks or other characters not
found in Table 1 must be ignored by decoding software. In base64
data, characters other than those in Table 1, line breaks, and other
white space probably indicate a transmission error, about which a
warning message or even a message rejection might be appropriate
under some circumstances.

Special processing is performed if fewer than 24 bits are available
at the end of the data being encoded. A full encoding quantum is
always completed at the end of a body. When fewer than 24 input bits
are available in an input group, zero bits are added (on the right)
to form an integral number of 6-bit groups. Padding at the end of
the data is performed using the "=" character. Since all base64
input is an integral number of octets, only the following cases can
arise: (1) the final quantum of encoding input is an integral
multiple of 24 bits; here, the final unit of encoded output will be
an integral multiple of 4 characters with no "=" padding, (2) the
final quantum of encoding input is exactly 8 bits; here, the final
unit of encoded output will be two characters followed by two "="
padding characters, or (3) the final quantum of encoding input is
exactly 16 bits; here, the final unit of encoded output will be three
characters followed by one "=" padding character.

Because it is used only for padding at the end of the data, the
occurrence of any "=" characters may be taken as evidence that the
end of the data has been reached (without truncation in transit). No
such assurance is possible, however, when the number of octets
transmitted was a multiple of three and no "=" characters are
present.

Any characters outside of the base64 alphabet are to be ignored in
base64-encoded data.

Care must be taken to use the proper octets for line breaks if base64
encoding is applied directly to text material that has not been
converted to canonical form. In particular, text line breaks must be
converted into CRLF sequences prior to base64 encoding. The
important thing to note is that this may be done directly by the
encoder rather than in a prior canonicalization step in some
implementations.

NOTE: There is no need to worry about quoting potential boundary
delimiters within base64-encoded bodies within multipart entities
because no hyphen characters are used in the base64 encoding.
f26511314 2002-10-22
  • 打赏
  • 举报
回复
to: core(酒载青山)
你举个例子可以吗?
加载更多回复(3)

16,548

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • AIGC Browser
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧