Base64解码和QP解码

前段时间在做邮件解码的时候碰到MIME的Base64编码和QP编码

1.Base64编码

  Base64要求把3个8位字节(3*8=24)转化为4个6位的字节(4*6=24),之后在6位的前面补两个0,形成8位一个字节的形式.

  解码算法大概可以分为如下几步几步: 

  读取数据3字节用AND取前6位,放入新的变量中右移两位,高两位清0AND取第一个字节的后2位和第二个字节的前4位移位放入新变量中右移两位,清0……依此类推。

代码
// 解码后的长度一般比原文少用占1/4的存储空间,请保证buf有足够的空间
inline int Base64Decode(char * buf, const char * base64code, int src_len) 
{   
    
if (src_len == 0)
        src_len 
= strlen(base64code);

    
int len = 0;
    unsigned 
char* psrc = (unsigned char*)base64code;
    
char * pbuf = buf;
    
int i ;
    
for ( i = 0; i < src_len - 4; i += 4)
    {
        unsigned 
long ulTmp = *(unsigned long*)psrc;

        register 
int b0 = (GetB64Index((char)B0(ulTmp)) << 2 | GetB64Index((char)B1(ulTmp)) << 2 >> 6& 0xFF;
        register 
int b1 = (GetB64Index((char)B1(ulTmp)) << 4 | GetB64Index((char)B2(ulTmp)) << 2 >> 4& 0xFF;
        register 
int b2 = (GetB64Index((char)B2(ulTmp)) << 6 | GetB64Index((char)B3(ulTmp)) << 2 >> 2& 0xFF;

 
//       *((unsigned long*)pbuf) = b0 | b1 << 8 | b2 << 16;
        *pbuf++ = b0;
        
*pbuf++ = b1;
        
*pbuf++ = b2;

        psrc  
+= 4
//        pbuf += 4;
        len += 3;
    }

    
// 处理最后余下的不足4字节的数据
    if (i < src_len)
    {
        
int rest = src_len - i;
        unsigned 
long ulTmp = 0;
        
for (int j = 0; j < rest; ++j)
        {
            
*(((unsigned char*)&ulTmp) + j) = *psrc++;
        }

        register 
int b0 = (GetB64Index((char)B0(ulTmp)) << 2 | GetB64Index((char)B1(ulTmp)) << 2 >> 6& 0xFF;
        
*pbuf++ = b0;
        len  
++;

        
if ('=' != B1(ulTmp) && '=' != B2(ulTmp))
        {
            register 
int b1 = (GetB64Index((char)B1(ulTmp)) << 4 | GetB64Index((char)B2(ulTmp)) << 2 >> 4& 0xFF;
            
*pbuf++ = b1;
            len  
++;
        }

        
if ('=' != B2(ulTmp) && '=' != B3(ulTmp))
        {
            register 
int b2 = (GetB64Index((char)B2(ulTmp)) << 6 | GetB64Index((char)B3(ulTmp)) << 2 >> 2& 0xFF;
            
*pbuf++ = b2;
            len  
++;
        }

    }

    
*pbuf = '\0'

    
return len;

2.QP(Quote-Printable)编码

   Quoted-Printable编码的基本方法是:输入数据在33-60、62-126范围内的,直接输出;其它的需编码为“=”加两个字节的HEX码(大写)。为保证输出行不超过规定长度,可在行尾加“=\r\n”序列作为软回车。

QP的解码算法: 

代码
inline int DecodeQuoted( char* pDst,const char* pSrc, int nSrcLen)
{
    
if (nSrcLen == 0)
        nSrcLen 
= strlen(pSrc);
    
int nDstLen;        // 输出的字符计数
    int i;

    i 
= 0;
    nDstLen 
= 0;

    
while (i < nSrcLen)
    {
        
if (strncmp(pSrc, "=\r\n"3== 0)        // 软回车,跳过
        {
            pSrc 
+= 3;
            i 
+= 3;
        }
        
else
        {
            
if (*pSrc == '=')        // 是编码字节
            {
                sscanf(pSrc, 
"=%02X", pDst);
                pDst
++;
                pSrc 
+= 3;
                i 
+= 3;
            }
            
else        // 非编码字节
            {
                
*pDst++ = (unsigned char)*pSrc++;
                i
++;
            }

            nDstLen
++;
        }
    }

    
// 输出加个结束符
    *pDst = '\0';

    
return nDstLen;
}

  

原文地址:https://www.cnblogs.com/alwaysyouare/p/1640496.html