base64解码图片,搞不定啊

ht_qq0609 2010-05-29 05:23:35
用c#很容易
byte[] temp = Convert.FromBase64String(strbase);
File.WriteAllBytes(@"d:\d1.png", temp);
这样就好了,而且保存的文件也没有问题。

可以用vc就总是不行。网上找了2个算法,解码后两个值都不相同,跟c#解析出来的也不同。保存成文件后,能显示图片的大小,可是图片总是打不开。

两种算法,如下:
//Base64 解码
static char GetBase64Value(char ch) //得到编码值
{
if ((ch >= 'A') && (ch <= 'Z')) // A ~ Z
return ch - 'A';
if ((ch >= 'a') && (ch <= 'z')) // a ~ z
return ch - 'a' + 26;
if ((ch >= '0') && (ch <= '9')) // 0 ~ 9
return ch - '0' + 52;
switch (ch) // 其它字符
{
case '+':
return 62;
case '/':
return 63;
case '=': //Base64 填充字符
return 0;
default:
return 0;
}
}
// 解码函数
static int Base64Decode( char *OrgString, char *Base64String, int Base64StringLen, bool bForceDecode ) //解码函数
{
// OrgString 保存解码结果字符串指针
// Base64String 待解码字符串指针
// Base64StringLen 待解码字符串长度
// bForceDecode 当待解码字符串长度错误时,是否强制解码
// true 强制解码
// false 不强制解码
if( Base64StringLen % 4 && !bForceDecode ) //如果不是 4 的倍数,则 Base64 编码有问题
{
OrgString[0] = '\0';
return -1;
}
unsigned char Base64Encode[4];
int OrgStringLen=0;

while( Base64StringLen > 2 ) //当待解码个数不足3个时,将忽略它(强制解码时有效)
{
Base64Encode[0] = GetBase64Value(Base64String[0]);
Base64Encode[1] = GetBase64Value(Base64String[1]);
Base64Encode[2] = GetBase64Value(Base64String[2]);
Base64Encode[3] = GetBase64Value(Base64String[3]);

*OrgString ++ = (Base64Encode[0] << 2) | (Base64Encode[1] >> 4);
*OrgString ++ = (Base64Encode[1] << 4) | (Base64Encode[2] >> 2);
*OrgString ++ = (Base64Encode[2] << 6) | (Base64Encode[3]);

Base64String += 4;
Base64StringLen -= 4;
OrgStringLen += 3;
}

return OrgStringLen;
}
static long bBase64Decode( string &OrgString,const char* pSrc,int nSrcLen)
{
int nValue,i=0;
const char DeBase64Tab[]=
{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
62, // '+'
0, 0, 0,
63, // '/'
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, // '0'-'9'
0, 0, 0, 0, 0, 0, 0,
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, // 'A'-'Z'
0, 0, 0, 0, 0, 0,
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, // 'a'-'z'
};
// 取4个字符,解码到一个长整数,再经过移位得到3个字节
while (i < nSrcLen)
{
if (*pSrc != '\r' && *pSrc!='\n')
{
nValue = DeBase64Tab[*pSrc++] << 18;
nValue += DeBase64Tab[*pSrc++] << 12;
OrgString += (nValue & 0x00ff0000) >> 16;

if (*pSrc != '=')
{
nValue += DeBase64Tab[*pSrc++] << 6;
OrgString += (nValue & 0x0000ff00) >> 8;

if (*pSrc != '=')
{
nValue += DeBase64Tab[*pSrc++];
OrgString +=nValue & 0x000000ff;
}
}

i += 4;
}
else // 回车换行,跳过
{
pSrc++;
i++;
}
}
return OrgString.length();
}

谢谢大家,着急
...全文
604 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
那城 2012-07-25
  • 打赏
  • 举报
回复
要把他写成二进制类型,转换成字符串,会丢信息,而且影响解析
nixihz1990 2012-07-18
  • 打赏
  • 举报
回复
自己提问 自己解决。
leoj23 2012-07-18
  • 打赏
  • 举报
回复
ATL 提供现成的编码和解码函数
hellodota121 2010-05-31
  • 打赏
  • 举报
回复
友情帮顶
h243624 2010-05-31
  • 打赏
  • 举报
回复
byte位有错位吧
arong1234 2010-05-30
  • 打赏
  • 举报
回复
base64编码、解码之所以必须,是因为原始数据不是字符串,它中间包含了'\0'
你的编解码中似乎还是把数据当字符串来处理,当然是有问题的。
ht_qq0609 2010-05-30
  • 打赏
  • 举报
回复
自己搞定了,从atl里面扣出来的。
#ifndef ATLASSERT
#define ATLASSERT(expr) _ASSERTE(expr)
#endif // ATLASSERT
int Base64DecodeGetRequiredLength(int nSrcLen) throw()
{
return nSrcLen;
}

int DecodeBase64Char(unsigned int ch) throw()
{
// returns -1 if the character is invalid
// or should be skipped
// otherwise, returns the 6-bit code for the character
// from the encoding table
if (ch >= 'A' && ch <= 'Z')
return ch - 'A' + 0; // 0 range starts at 'A'
if (ch >= 'a' && ch <= 'z')
return ch - 'a' + 26; // 26 range starts at 'a'
if (ch >= '0' && ch <= '9')
return ch - '0' + 52; // 52 range starts at '0'
if (ch == '+')
return 62;
if (ch == '/')
return 63;
return -1;
}

BOOL Base64Decode(LPCSTR szSrc, int nSrcLen, BYTE *pbDest, int *pnDestLen) throw()
{
// walk the source buffer
// each four character sequence is converted to 3 bytes
// CRLFs and =, and any characters not in the encoding table
// are skiped

if (szSrc == NULL || pnDestLen == NULL)
{
ATLASSERT(FALSE);
return FALSE;
}

LPCSTR szSrcEnd = szSrc + nSrcLen;
int nWritten = 0;

BOOL bOverflow = (pbDest == NULL) ? TRUE : FALSE;

while (szSrc < szSrcEnd &&(*szSrc) != 0)
{
DWORD dwCurr = 0;
int i;
int nBits = 0;
for (i=0; i<4; i++)
{
if (szSrc >= szSrcEnd)
break;
int nCh = DecodeBase64Char(*szSrc);
szSrc++;
if (nCh == -1)
{
// skip this char
i--;
continue;
}
dwCurr <<= 6;
dwCurr |= nCh;
nBits += 6;
}

if(!bOverflow && nWritten + (nBits/8) > (*pnDestLen))
bOverflow = TRUE;

// dwCurr has the 3 bytes to write to the output buffer
// left to right
dwCurr <<= 24-nBits;
for (i=0; i<nBits/8; i++)
{
if(!bOverflow)
{
*pbDest = (BYTE) ((dwCurr & 0x00ff0000) >> 16);
pbDest++;
}
dwCurr <<= 8;
nWritten++;
}

}

*pnDestLen = nWritten;

if(bOverflow)
{
if(pbDest != NULL)
{
ATLASSERT(FALSE);
}

return FALSE;
}

return TRUE;
}

使用
main()
{
int nDecLen = Base64DecodeGetRequiredLength(strValue.length());
char *pDec = new char[nDecLen+1];
memset(pDec,0,nDecLen+1);
Base64Decode(strValue.c_str(),strValue.length(),(BYTE*)pDec,&nDecLen);
//write file
}
budweiser 2010-05-29
  • 打赏
  • 举报
回复
友情帮顶
mayonglong 2010-05-29
  • 打赏
  • 举报
回复
不懂,帮顶~~

33,007

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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