一个字符串用 base64编码的,但是解码的时候不支持中文,请问谁能够提供一个方法让他支持下中文啊。
解决方案 »
- atl如何在win7 64位 IE9下调试呢?IDispatch::Invoke会崩溃
- 关于connect函数中的sockaddr参数能不能用hostname而不用ip
- 怎样判断捕获的数据报是发送给本机或者本机发出去的?
- 请问,VC开发数据库有什么书是值得读的?
- 用AfxBeginThread好还是CreatThread好?
- 高手急救,怎么切换计算机的管理员帐号啊?
- 为什么我的函数调用会出错?
- 如何改变IPAddress的背景色?
- 谁有类filemon的源代码,请给我一份,谢谢!
- 在序列化数据时,为何0.25M数据只需1分钟,存1M数据确要30分钟?急!急!急!
- ATL编写服务程序,如何修改服务的依赖?
- 请问一下无法解析的外部符号的问题?
统一按二进制加密解密.
移植一下就可以用
HRESULT CSimpleLogObj::ToBase64(LPVOID pv, ULONG cbStart, BSTR* pbstr)
//
// Encode and return the bytes in base 64
//
{
ULONG cb = cbStart;
*pbstr = NULL;
HRESULT hr = S_OK;
int cchPerLine = 72; // conservative, must be mult of 4 for us
int cbPerLine = cchPerLine / 4 * 3;
int cbSafe = cb + 3; // allow for padding
int cLine = cbSafe / cbPerLine + 2; // conservative
int cchNeeded = cLine * (cchPerLine + 2 /*CRLF*/) + 1 /*NULL*/;
int cbNeeded = cchNeeded * sizeof(WCHAR);
LPWSTR wsz = (LPWSTR)CoTaskMemAlloc(cbNeeded);
if (wsz)
{
BYTE* pb = (BYTE*)pv;
WCHAR* pch = wsz;
int cchLine = 0;
//
// Main encoding loop
//
while (cb >= 3)
{
BYTE b0 = ((pb[0]>>2) & 0x3F);
BYTE b1 = ((pb[0]&0x03)<<4) | ((pb[1]>>4) & 0x0F);
BYTE b2 = ((pb[1]&0x0F)<<2) | ((pb[2]>>6) & 0x03);
BYTE b3 = ((pb[2]&0x3F));
*pch++ = rgwchBase64[b0];
*pch++ = rgwchBase64[b1];
*pch++ = rgwchBase64[b2];
*pch++ = rgwchBase64[b3];
pb += 3;
cb -= 3;
// put in line breaks
cchLine += 4;
if (cchLine >= cchPerLine)
{
*pch++ = L'\r';
*pch++ = L'\n';
cchLine = 0;
}
}
//
// Account for gunk at the end
//
*pch++ = L'\r'; // easier than keeping track
*pch++ = L'\n';
if (cb==0)
{
// nothing to do
}
else if (cb==1)
{
BYTE b0 = ((pb[0]>>2) & 0x3F);
BYTE b1 = ((pb[0]&0x03)<<4) | 0;
*pch++ = rgwchBase64[b0];
*pch++ = rgwchBase64[b1];
*pch++ = L'=';
*pch++ = L'=';
}
else if (cb==2)
{
BYTE b0 = ((pb[0]>>2) & 0x3F);
BYTE b1 = ((pb[0]&0x03)<<4) | ((pb[1]>>4) & 0x0F);
BYTE b2 = ((pb[1]&0x0F)<<2) | 0;
*pch++ = rgwchBase64[b0];
*pch++ = rgwchBase64[b1];
*pch++ = rgwchBase64[b2];
*pch++ = L'=';
}
//
// NULL terminate the string
//
*pch = NULL;
//
// Allocate our final output
//
*pbstr = SysAllocString(wsz);
if (*pbstr==NULL)
hr = E_OUTOFMEMORY;
CoTaskMemFree(wsz);
}
else
hr = E_OUTOFMEMORY;
#ifdef _DEBUG
if (hr==S_OK)
{
BLOB b;
FromBase64(*pbstr, &b);
_ASSERTE(b.cbSize == cbStart);
_ASSERTE(memcmp(b.pBlobData, pv, cbStart) == 0);
CoTaskMemFree(b.pBlobData);
}
#endif
return hr;
}
HRESULT CSimpleLogObj::FromBase64(BSTR bstr, BLOB* pblob)
//
// Decode and return the Base64 encoded bytes
//
{
HRESULT hr = S_OK;
int cbNeeded = lstrlenW(bstr); // an upper bound
BYTE* rgb = (BYTE*)CoTaskMemAlloc(cbNeeded);
if (rgb)
{
BYTE mpwchb[256];
BYTE bBad = (BYTE)-1;
int i;
//
// Initialize our decoding array
//
memset(&mpwchb[0], bBad, 256);
for (i = 0; i < 64; i++)
{
WCHAR wch = rgwchBase64[i];
mpwchb[wch] = i;
}
//
// Loop over the entire input buffer
//
ULONG bCurrent = 0; // what we're in the process of filling up
int cbitFilled = 0; // how many bits in it we've filled
BYTE* pb = rgb; // current destination (not filled)
//
for (WCHAR* pwch=bstr; *pwch; pwch++)
{
WCHAR wch = *pwch;
//
// Ignore white space
//
if (wch==0x0A || wch==0x0D || wch==0x20 || wch==0x09)
continue;
//
// Have we reached the end?
//
if (wch==L'=')
break;
//
// How much is this character worth?
//
BYTE bDigit = mpwchb[wch];
if (bDigit==bBad)
{
hr = E_INVALIDARG;
break;
}
//
// Add in its contribution
//
bCurrent <<= 6;
bCurrent |= bDigit;
cbitFilled += 6;
//
// If we've got enough, output a byte
//
if (cbitFilled >= 8)
{
ULONG b = (bCurrent >> (cbitFilled-8)); // get's top eight valid bits
*pb++ = (BYTE)(b&0xFF); // store the byte away
cbitFilled -= 8;
}
}
if (hr==S_OK)
{
pblob->pBlobData = rgb;
pblob->cbSize = pb-rgb;
}
else
{
CoTaskMemFree(rgb);
pblob->pBlobData = NULL;
}
}
else
hr = E_OUTOFMEMORY;
return hr;
}