迅雷加密的下载链接地址,使用了BASE64加密算法。BASE64算法是一个可逆的算法,所以可以用来进行简单的加密!
我们在下载一些网络资源的时候,常常会见到类似于如下的链接地址:
在Windows中如果安装了迅雷,就可以正确解析这样的地址,其实这样一串字符就是用BASE64算法经加密后得到的,我用“
http://image2.sina.com.cn/blog/tmpl/v3/images/logo.gif”作为例说明一下整个加密和解密的过程。
加密:
在完整的下载链接前冠以“AA”,后缀以“ZZ”:
AA
http://image2.sina.com.cn/blog/tmpl/v3/images/logo.gifZZ
用BASE64算法进行加密,得到:
QUFodHRwOi8vaW1hZ2UyLnNpbmEuY29tLmNuL2Jsb2cvdG1wbC92My9pbWFnZXMvbG9nby5naWZaWg==
在前面加上迅雷自己的协议头:
大功告成!
解密:
把以上过程逆向一下就可以了:
去掉迅雷协议头;用BASE64算法解密;去掉“AA”、“ZZ”!附上base64的加密算法 留着有空研究static size_t _base64Decode(unsigned char* pszNormal, const unsigned char* pczBase64, int nSize)
{
ASSERT(nSize > ZERO);
unsigned char* pszBase64Copy = NULL;
if( pczBase64 == pszNormal )
{
pszBase64Copy = new unsigned char[nSize]; ASSERT(pszBase64Copy);
::memcpy(pszBase64Copy, pczBase64, nSize);
}
size_t nsize = 0;
unsigned char* pucOrig = (NULL == pszBase64Copy) ? (unsigned char*)pczBase64 : pszBase64Copy;
unsigned char* pucDest = pszNormal;
for(int nNow = 0; nNow < nSize - 4; nNow += 4)
{
unsigned long ul = *(unsigned long*)pucOrig;
register int b0 = (_getBase64Index((char)B0(ul))<<2|_getBase64Index((char)B1(ul))<<2>>6)&MAX_BYTE;
register int b1 = (_getBase64Index((char)B1(ul))<<4|_getBase64Index((char)B2(ul))<<2>>4)&MAX_BYTE;
register int b2 = (_getBase64Index((char)B2(ul))<<6|_getBase64Index((char)B3(ul))<<2>>2)&MAX_BYTE;
*((unsigned long*)pucDest) = b0|b1<<8|b2<<16;
pucOrig += 4;
pucDest += 3;
nsize += 3;
}
if( nNow < nSize )
{
int nRest = nSize - nNow;
unsigned long ul = 0;
for(int j = 0; j < nRest; ++j){
*(((unsigned char*)&ul)+j) = *pucOrig++;
}
register int b0 = (_getBase64Index((char)B0(ul))<<2|_getBase64Index((char)B1(ul))<<2>>6)&MAX_BYTE;
*pucDest++ = b0;
nsize++;
if( (_EQ_ != B1(ul)) && (_EQ_ != B2(ul)) )
{
register int b1 = (_getBase64Index((char)B1(ul))<<4|_getBase64Index((char)B2(ul))<<2>>4)&MAX_BYTE;
*pucDest++ = b1;
nsize++;
}
if( (_EQ_ != B2(ul)) && (_EQ_ != B3(ul)) )
{
register int b2 = (_getBase64Index((char)B2(ul))<<6|_getBase64Index((char)B3(ul))<<2>>2)&MAX_BYTE;
*pucDest++ = b2;
nsize++;
}
}
*pucDest = _EOS_;
if( pszBase64Copy )
{
delete[] pszBase64Copy;
pszBase64Copy = NULL;
}
return nsize;
}
static int _base64Encode(unsigned char* pszBase64, const unsigned char* pczNormal, int nSize)
{
ASSERT(nSize > ZERO);
unsigned char* pszNormalCopy = NULL;
if( pczNormal == pszBase64 )
{
pszNormalCopy = new unsigned char[nSize];
::memcpy(pszNormalCopy, pczNormal, nSize);
}
size_t nsize = 0;
unsigned char* pucOrig = (NULL == pszNormalCopy) ? (unsigned char*)pczNormal : pszNormalCopy;
unsigned char* puc64 = pszBase64;
for(int nNow = 0; nNow < nSize - 3; nNow += 3)
{
unsigned long ul = *(unsigned long*)pucOrig;
register int b0 = _getBase64Char((B0(ul) >> 2) & 0x3F);
register int b1 = _getBase64Char((B0(ul) << 6 >> 2 | B1(ul) >> 4) & 0x3F);
register int b2 = _getBase64Char((B1(ul) << 4 >> 2 | B2(ul) >> 6) & 0x3F);
register int b3 = _getBase64Char((B2(ul) << 2 >> 2) & 0x3F);
*((unsigned long*)puc64) = b0 | b1 << 8 | b2 << 16 | b3 << 24;
nsize += 4;
puc64 += 4;
pucOrig += 3;
}
if( nNow < nSize )
{
int nRest = nSize - nNow;
unsigned long ul = 0;
for(int j = 0; j < nRest; ++j){
*(((unsigned char*)&ul) + j) = *pucOrig++;
}
puc64[0] = _getBase64Char((B0(ul) >> 2) & 0x3F);
puc64[1] = _getBase64Char((B0(ul) << 6 >> 2 | B1(ul) >> 4) & 0x3F);
puc64[2] = (nRest > 1)?_getBase64Char((B1(ul) << 4 >> 2 | B2(ul) >> 6) & 0x3F) : _EQ_;
puc64[3] = (nRest > 2)?_getBase64Char((B2(ul) << 2 >> 2) & 0x3F) : _EQ_;
puc64 += 4;
nsize += 4;
}
*puc64 = _EOS_;
if( pszNormalCopy )
{
delete[] pszNormalCopy;
pszNormalCopy = NULL;
}
return nsize;
}