C++实现Base32加解码

Base32 是一种将任意字符串重新编码成5bit一组的可显字符串的编码算法

#ifndef YBASE32_H
#define YBASE32_H

#include <string>

class YBase32{
public:
    static int toBase32Length(int count);
    static int fromBase32Length(int count);

    static void toBase32(char* dest, const char* src, int length);
    static void fromBase32(char* dest, const char* src, int length);

    static std::string toBase32(const std::string& string);
    static std::string fromBase32(const std::string& string);
};

#endif // YBASE32_H

#include "YBase32.h"
#include "string.h"

static char map[33] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ012345";
static uint8_t reverse_map[96] = {
    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
    255, 255, 24, 25, 26, 27, 28, 29, 30, 31, 255, 255, 255, 255, 255, 255,
    255, 0, 1, 2, 3, 4, 5, 6, 7, 255, 8, 9, 10, 11, 12, 255,
    13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 255, 255, 255, 255, 255,
};

int YBase32::toBase32Length(int count)
{
    int byteCount = count * 8;
    int length = byteCount / 5;
    if(byteCount % 5 != 0){
        ++length;
    }
    return length;
}

int YBase32::fromBase32Length(int count)
{
    return count * 5 / 8;
}

//https://gitee.com/YuanDad
namespace YBase32NameSpace {
template <typename T>
inline T QyAbs(const T &t) { return t >= 0 ? t : -t; }
}
//https://gitee.com/YuanDad

using namespace YBase32NameSpace;
//https://gitee.com/YuanDad

static char mask[5] = {1, 3, 7, 15, 31};
void YBase32::toBase32(char *dest, const char *src, int length)
{
    int left = 0, maxLength = length * 8, cursor = 0;
    while(true){
        int right = left + 5;
        if(right < maxLength){
            int x = left / 8, used = left % 8, remain = 8 - used;
            int tmp = 0;
            if(remain < 5){
                tmp = (src[x] & mask[remain - 1]) << (5 - remain);
                tmp += uchar(src[x + 1]) >> (3 + remain);
            }else{
                tmp = (src[x] >> (remain - 5) & mask[4]);
            }
            dest[cursor] = map[QyAbs(tmp)];
        }else if(right > maxLength){
            int tmp = (src[length - 1] & mask[maxLength - left - 1]) << (right - maxLength);
            dest[cursor] = map[QyAbs(tmp)];
            return;
        }else{
            int tmp = src[length - 1] & mask[4];
            dest[cursor] = map[QyAbs(tmp)];
            return;
        }
        ++cursor;
        left = right;
    }
}

void YBase32::fromBase32(char *dest, const char *src, int length)
{
    int left = 0, maxLength = fromBase32Length(length) * 8, cursor = 0;
    while(true){
        int right = left + 8;
        int x = left / 5, used = left % 5, count = 5 - used, sum = count;
        dest[cursor] = static_cast<char>(reverse_map[static_cast<uint>(src[x])] & mask[count - 1]);
        if(count < 3){
            ++x;
            sum += 5;
            dest[cursor] = static_cast<char>(dest[cursor] << 5) + reverse_map[static_cast<uint>(src[x])];
        }
        if(sum < 8){
            int remain = 8 - sum;
            dest[cursor] = static_cast<char>(dest[cursor] << remain) + (reverse_map[static_cast<uint>(src[x + 1])] >> (5 - remain));
        }

        if(right == maxLength){
            return;
        }

        ++cursor;
        left = right;
    }
}

std::string YBase32::toBase32(const std::string &string)
{
    std::string result(static_cast<size_t>(toBase32Length(static_cast<int>(string.size()))), '\0');
    toBase32(const_cast<char*>(result.data()), string.data(), static_cast<int>(string.size()));
    return result;
}

std::string YBase32::fromBase32(const std::string &string)
{
    std::string result(static_cast<size_t>(fromBase32Length(static_cast<int>(string.size()))), '\0');
    fromBase32(const_cast<char*>(result.data()), string.data(), static_cast<int>(string.size()));
    return result;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

向娇葵

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值