加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

16进制和64进制编码base16base64hex

(2019-08-05 10:48:30)
分类: 程序设计

template
class BaseMod
{
public:
    const static unsigned char decStop = 255u;
    const static unsigned char decSkip = 254u;
    const unsigned char* const encstr;
   
private:
 const char* m_err;

protected:
    unsigned char m_dectab[256];
 void clearError(void){ m_err = 0u; }
 void setError(const char* err){ m_err = err; }

public:
   
    BaseMod(const char* encodeStr): encstr(reinterpret_cast(encodeStr)), m_err(0u) {
        for(int i=0; i!= 256; ++i) m_dectab[i] = decStop; //基类构造函数先执行
        for(const char* p = " \t\r\n"; *p; ++p) m_dectab[*p] = decSkip;//设置解码时,错过空白字符
       
    }
    const char* error(void){ return m_err; }

 virtual int getEncodeLen(const int nEncByteCount)=0;
 
    //编码接口,完成后生成一个编码串(尾部添加空字符),返回串长
    //此接口除非传入非法参数,否则不可能错误,所以无捡错机制
    virtual int encode(const char* in, const int inLen, Char* out) = 0;     

    //解码接口,输入是以base16或base64格式的编码串,返回解码之后的字节数。成功执行返回>0
    //解码字符之间可以存在空白字符,但不可存在非编码字符,它的有效字符总数应是2或4的整数倍,否则函数将会设置一个错误
    //调用此函数之后,应调用接口,if(!getError()) 捡查是否成功执行
    virtual int decode(const Char* in, const int inLen, char* out) = 0;

    ~BaseMod(void){
         //static_assert(sizeof(uint16) == 2, "uint16 not is 4 byte");
         //static_assert(sizeof(uint32) == 4, "uint32 not is 4 byte");
        //基于本模块的字符类型必须只占1或2字节的内存
        static_assert( sizeof(Char) == 1 || sizeof(Char) == 2 , "Char type only can is one byte or two byte");
    }
};

 


template class Base16: public BaseMod
{
public:
    Base16(const bool xiao = true): BaseMod( xiao ?  "0123456789abcdef" : "0123456789ABCDEF"){
        for(int i=0; i!= 16; ++i) m_dectab[encstr[i]] = i;
    }

 int getEncodeLen(const int nEncByteCount){ return nEncByteCount*2; }

    int encode(const char* in, const int inLen, Char* out){
        int i = 0;
        for(const unsigned char* p = reinterpret_cast(in); i
          *out++ = encstr[p[i] >> 4];
          *out++ = encstr[(p[i] & 0x0f)];
        }
        *out = 0;
        return i*2;
    }

    //
    int decode(const Char* in, const int inLen, char* out){
        int i=0, o = 0;
        unsigned char n = 0;
        unsigned char* p = reinterpret_cast(out);
        clearError();
        for(; i
            if(in[i] > decStop) { setError("illegal encode char.");  break; }
            n = m_dectab[in[i]];
            if(decStop == n) { setError("illegal encode char.");  break; }
            if(decSkip == n) continue;
            if(0 == o){
            *p = n << 4;
               o = 1;
            }else{
              *p = *p | n;
              o = 0;  ++p;
                     
        }
        if(1==o)if(!error()) setError("this encode string size not is Multiple of 2");
        return p - reinterpret_cast(out);
    }
};

 

 

 

 

template class Base64: public BaseMod
{
public:
    Base64(void): BaseMod( "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" ){
        for(int i=0; i!= 64; ++i) m_dectab[encstr[i]] = i;
    }

 int getEncodeLen(const int nEncByteCount){
  int group = nEncByteCount / 3;
  int mod = nEncByteCount % 3;
  return (group * 4) + (mod ? 4 : 0);
 }

    int encode(const char* in, const int inLen, Char* out){
        int i = inLen;
        Char* const outbeg = out;
        const unsigned char* p = reinterpret_cast(in);
 //开始编码,输入每3字节为一分组(p组),输出每4字节为一分组(o组), 方括号内位运算的结果是编码索引(假定名为t,不大于63)
 for(; i>2; i -= 3)
 {
 out[0] = encstr[ p[0] >> 2                   ];//取p组首字节高6位放入t的低六位,据t值在表中找到对应字符,将该字符放入o组首字节
 out[1] = encstr[ ((p[0]&3u)<<4) | (p[1]>>4)  ];//取p组首字节低2位放入t的6至5位,取p组第2字节高4位放入t的低4位,
 out[2] = encstr[ ((p[1]&15u)<<2) | (p[2]>>6) ];//取p组第2字节低4位放入t的6至3位,取p组第3字节高2位放入t的低2位,
 out[3] = encstr[ p[2] & 63u                  ];//取p组第3字节低6位放入t的低6位,
 out += 4;  p += 3;
 }
 if(i==2)
 {
 out[0] = encstr[ p[0] >> 2                   ];
 out[1] = encstr[ ((p[0]&3u)<<4) | (p[1]>>4)  ];
 out[2] = encstr[ ((p[1]&15u)<<2)             ];
 out[3] = '=';      out += 4;
 }else if(i==1)
 {
 out[0] = encstr[ p[0] >> 2                   ];
 out[1] = encstr[ ((p[0]&3u)<<4)              ];
 out[2] = '=';
 out[3] = '=';      out += 4;
 }
        *out = '\0';
        return out - outbeg;
    }

    //
    int decode(const Char* in, const int inLen, char* out){
        int i=0, groupIndex = 0;
        unsigned char n=0;
        unsigned char* p = reinterpret_cast(out);
        clearError();
        for(; i
            if(in[i] > decStop) break;
            n = m_dectab[in[i]];
            if(decStop == n)  break;
            if(decSkip == n) continue;
            p[groupIndex] = n;
            if(3 == groupIndex){
                p[0] = (p[0] << 2) | (p[1] >> 4);
                p[1] = (p[1] << 4) | (p[2] >> 2);
                p[2] = ((p[2] & 3u) << 6) | p[3];
                groupIndex = 0;  p += 3;
            }else ++groupIndex;          
        }
        if(i < inLen){
           if('=' == in[i])
           {
              p[0] = (p[0] << 2) | (p[1] >> 4);
              if(2==groupIndex){ ++p; *p = *p << 4; }
              else if(3==groupIndex)
              {
                 p[1] = (p[1] << 4) | (p[2] >> 2);
                 p[2] = (p[2] & 3u) << 6;
                 p += 2;               
              }
              else setError("the encode string tail, before of equal less then two byte");
            }
            else setError("illegal encode char.");
        }else if(groupIndex) setError("this encode string size not is Multiple of 4");
       
        return p - reinterpret_cast(out);
    }
};

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有