c++ base3264

//
// Created by Amazing on 2024/12/22.
//

#ifndef BASE3264_H
#define BASE3264_H
#include <string>
#include <string.h>

class Base32 {
public:
    static std::string encode(const std::string& data);
    static char* encode(const char* data, size_t dataSize);
    static std::string decode(const std::string& code);
    static char* decode(const char* code, size_t& dataSize);
private:
    static const std::string _32keyStr;
};
const std::string Base32::_32keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567=";

class Base64 {
public:
    static std::string encode(const std::string& data);
    static char* encode(const char* data, size_t dataSize);
    static std::string decode(const std::string& code);
    static char* decode(const char* code, size_t& dataSize);
private:
    static const std::string _64keyStr;
};
const std::string Base64::_64keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";

char* Base32::encode(const char *data, size_t dataSize) {
    if (dataSize == 0) return nullptr;
    // Base32 是每5个bit编码成一个字符,一个char8个bit,那么每次需要拿5个char共40(5*8=40)个bit,然后拆分成8个5bit
    // |xxxxxxxx|xxxxxxxx|xxxxxxxx|xxxxxxxx|xxxxxxxx|
    // |xxxxx|xxxxx|xxxxx|xxxxx|xxxxx|xxxxx|xxxxx|xxxxx|
    std::string encodeStr;
    size_t codeSize = (dataSize / 5 + (dataSize % 5 ? 1 : 0)) * 8 + 1;
    char* code = (char*) malloc(codeSize);
    memset(code, 0, codeSize);
    unsigned char c5[5], c8[8];
    size_t index = 0, tail = 0;
    while (index < dataSize) {
        memset(c5, 0, sizeof(c5));
        memset(c8, 0, sizeof(c8));
        size_t cSize = 5 < dataSize - index ? 5 : dataSize - index;
        for (int i = 0; i < cSize; ++i) c5[i] = data[index++];
        c8[0]=c5[0]>>3;
        c8[1]=(c5[0]&7)<<2|(c5[1]>>6);
        c8[2]=(c5[1]>>1)&31;
        c8[3]=((c5[1]&1)<<4)|(c5[2]>>4);
        c8[4]=((c5[2]&15)<<1)|(c5[3]>>7);
        c8[5]=(c5[3]>>2)&31;
        c8[6]=((c5[3]&3)<<3)|(c5[4]>>5);
        c8[7]=c5[4]&31;
        for (size_t i=cSize*8/5+1;i<8;++i) c8[i]=32;
        for (int i=0;i<8;++i) code[tail++]=_32keyStr[c8[i]];
    }
    return code;
}

std::string Base32::encode(const std::string &data) {
    // Base32 是每5个bit编码成一个字符,一个char8个bit,那么每次需要拿5个char共40(5*8=40)个bit,然后拆分成8个5bit
    // |xxxxxxxx|xxxxxxxx|xxxxxxxx|xxxxxxxx|xxxxxxxx|
    // |xxxxx|xxxxx|xxxxx|xxxxx|xxxxx|xxxxx|xxxxx|xxxxx|
    const size_t dataSize = data.size();
    if (dataSize == 0) return "";
    std::string encodeStr;
    size_t codeSize = (data.size() / 5 + (data.size() % 5 ? 1 : 0)) * 8;
    std::string code(codeSize, '\0');
    unsigned char c5[5], c8[8];
    size_t index = 0, tail = 0;
    while (index < dataSize) {
        memset(c5, 0, sizeof(c5));
        memset(c8, 0, sizeof(c8));
        size_t cSize = 5 < dataSize - index ? 5 : dataSize - index;
        for (int i = 0; i < cSize; ++i) c5[i] = data[index++];
        c8[0]=c5[0]>>3;
        c8[1]=(c5[0]&7)<<2|(c5[1]>>6);
        c8[2]=(c5[1]>>1)&31;
        c8[3]=((c5[1]&1)<<4)|(c5[2]>>4);
        c8[4]=((c5[2]&15)<<1)|(c5[3]>>7);
        c8[5]=(c5[3]>>2)&31;
        c8[6]=((c5[3]&3)<<3)|(c5[4]>>5);
        c8[7]=c5[4]&31;
        for (size_t i=cSize*8/5+1;i<8;++i) c8[i]=32;
        for (int i=0;i<8;++i) code[tail++]=_32keyStr[c8[i]];
    }
    return code;
}

char *Base32::decode(const char* code, size_t& dataSize) {
    const size_t codeSize = strlen(code);
    size_t maxDataSize = codeSize * 5 / 8;
    char* data = (char*)malloc(maxDataSize);
    memset(data, 0, maxDataSize);
    unsigned char c5[5], c8[8];
    size_t index = 0;
    dataSize = 0;
    while (index < codeSize) {
        memset(c5, 0, sizeof(c5));
        memset(c8, 0, sizeof(c8));
        size_t cSize = 8 < codeSize - index ? 8 : codeSize - index;
        for (int i = 0; i < cSize; ++i) c8[i] = _32keyStr.find(code[index++]);
        for (int i = cSize; i < 8; ++i) c8[i] = 32;
        c5[0] = (c8[0]<<3)|(c8[1]>>2);
        c5[1] = ((c8[1]&3)<<6)|(c8[2]<<1)|(c8[3]>>4);
        c5[2] = ((c8[3]&15)<<4)|(c8[4]>>1);
        c5[3] = ((c8[4]&1)<<7)|(c8[5]<<2)|(c8[6]>>3);
        c5[4] = ((c8[6]&7)<<5)|c8[7];
        int valiedSize = 7;
        while(valiedSize >= 0 && c8[valiedSize]==32) --valiedSize;
        valiedSize = (valiedSize + 1) * 5 / 8;
        for (int i=0;i<valiedSize;++i) data[dataSize++] = c5[i];
    }
    return data;
}

std::string Base32::decode(const std::string &code) {
    const size_t codeSize = code.size();
    if (codeSize * 5 % 8 != 0) return "";
    size_t maxDataSize = codeSize * 5 / 8;
    std::string data(maxDataSize, '\0');
    unsigned char c5[5], c8[8];
    size_t index = 0, dataSize = 0;
    while (index < codeSize) {
        memset(c5, 0, sizeof(c5));
        memset(c8, 0, sizeof(c8));
        size_t cSize = 8 < codeSize - index ? 8 : codeSize - index;
        for (int i = 0; i < cSize; ++i) c8[i] = _32keyStr.find(code[index++]);
        for (int i = cSize; i < 8; ++i) c8[i] = 32;
        c5[0] = (c8[0]<<3)|(c8[1]>>2);
        c5[1] = ((c8[1]&3)<<6)|(c8[2]<<1)|(c8[3]>>4);
        c5[2] = ((c8[3]&15)<<4)|(c8[4]>>1);
        c5[3] = ((c8[4]&1)<<7)|(c8[5]<<2)|(c8[6]>>3);
        c5[4] = ((c8[6]&7)<<5)|c8[7];
        int valiedSize = 7;
        while(valiedSize >= 0 && c8[valiedSize]==32) --valiedSize;
        valiedSize = (valiedSize + 1) * 5 / 8;
        for (int i=0;i<valiedSize;++i) data[dataSize++] = c5[i];
    }
    data.resize(dataSize);
    return data;
}

char *Base64::encode(const char *data, size_t dataSize) {
    // Base64 是每6个bit编码成一个字符,一个char8个bit,那么每次需要拿3个char共24(3*8=24)个bit,然后拆分成4个6bit
    // |xxxxxxxx|xxxxxxxx|xxxxxxxx|
    // |xxxxxx|xxxxxx|xxxxxx|xxxxxx|
    if (dataSize <= 0) return nullptr;
    size_t codeSize = (dataSize / 3 + (dataSize % 3 ? 1 : 0)) * 4 + 1;
    char* code = (char*)malloc(codeSize);
    memset(code, 0, codeSize);
    unsigned char c3[3], c4[4];
    size_t index = 0, tail = 0;
    while (index < dataSize) {
        memset(c3, 0, sizeof(c3));
        memset(c4, 0, sizeof(c4));
        size_t cSize = 3 < dataSize - index ? 3 : dataSize - index;
        for (int i = 0; i < cSize; ++i) c3[i] = data[index++];
        c4[0] = c3[0] >> 2;
        c4[1] = (c3[0] & 3) << 4 | c3[1] >> 4;
        c4[2] = (c3[1] & 15) << 2 | c3[2] >> 6;
        c4[3] = c3[2] & 63;
        for (size_t i=cSize*4/3+1;i<4;++i) c4[i]=64;
        for (int i=0;i<4;++i) code[tail++]=_64keyStr[c4[i]];
    }
    return code;
}

std::string Base64::encode(const std::string &data) {
    // Base64 是每6个bit编码成一个字符,一个char8个bit,那么每次需要拿3个char共24(3*8=24)个bit,然后拆分成4个6bit
    // |xxxxxxxx|xxxxxxxx|xxxxxxxx|
    // |xxxxxx|xxxxxx|xxxxxx|xxxxxx|
    const size_t dataSize = data.size();
    if (dataSize == 0) return "";
    std::string encodeStr;
    size_t codeSize = (data.size() / 3 + (data.size() % 3 ? 1 : 0)) * 4;
    std::string code(codeSize, '\0');
    unsigned char c3[3], c4[4];
    size_t index = 0, tail = 0;
    while (index < dataSize) {
        memset(c3, 0, sizeof(c3));
        memset(c4, 0, sizeof(c4));
        size_t cSize = 3 < dataSize - index ? 3 : dataSize - index;
        for (int i = 0; i < cSize; ++i) c3[i] = data[index++];
        c4[0] = c3[0] >> 2;
        c4[1] = (c3[0] & 3) << 4 | c3[1] >> 4;
        c4[2] = (c3[1] & 15) << 2 | c3[2] >> 6;
        c4[3] = c3[2] & 63;
        for (size_t i=cSize*4/3+1;i<4;++i) c4[i]=64;
        for (int i=0;i<4;++i) code[tail++]=_64keyStr[c4[i]];
    }
    return code;
}

char *Base64::decode(const char *code, size_t& dataSize) {
    const size_t codeSize = strlen(code);
    if (codeSize * 3 % 4 != 0) return nullptr;
    size_t maxDataSize = codeSize * 3 / 4;
    char* data = (char*)malloc(maxDataSize);
    memset(data, 0, maxDataSize);
    unsigned char c3[3], c4[4];
    size_t index = 0;
    dataSize = 0;
    while (index < codeSize) {
        memset(c3, 0, sizeof(c3));
        memset(c4, 0, sizeof(c4));
        size_t cSize = 4 < codeSize - index ? 4 : codeSize - index;
        for (int i = 0; i < cSize; ++i) c4[i] = _64keyStr.find(code[index++]);
        for (int i = cSize; i < 4; ++i) c4[i] = 64;
        c3[0] = (c4[0] << 2) | (c4[1] >> 4);
        c3[1] = ((c4[1] & 15) << 4) | (c4[2] >> 2);
        c3[2] = ((c4[2] & 3) << 6) | c4[3];
        int valiedSize = 3;
        while(valiedSize >= 0 && c4[valiedSize]==64) --valiedSize;
        valiedSize = (valiedSize + 1) * 6 / 8;
        for (int i=0;i<valiedSize;++i) data[dataSize++] = c3[i];
    }
    return data;
}

std::string Base64::decode(const std::string &code) {
    const size_t codeSize = code.size();
    if (codeSize * 3 % 4 != 0) return "";
    size_t maxDataSize = codeSize * 3 / 4;
    std::string data(maxDataSize, '\0');
    unsigned char c3[3], c4[4];
    size_t index = 0, dataSize = 0;
    while (index < codeSize) {
        memset(c3, 0, sizeof(c3));
        memset(c4, 0, sizeof(c4));
        size_t cSize = 4 < codeSize - index ? 4 : codeSize - index;
        for (int i = 0; i < cSize; ++i) c4[i] = _64keyStr.find(code[index++]);
        for (int i = cSize; i < 4; ++i) c4[i] = 64;
        c3[0] = (c4[0] << 2) | (c4[1] >> 4);
        c3[1] = ((c4[1] & 15) << 4) | (c4[2] >> 2);
        c3[2] = ((c4[2] & 3) << 6) | c4[3];
        int valiedSize = 3;
        while(valiedSize >= 0 && c4[valiedSize]==64) --valiedSize;
        valiedSize = (valiedSize + 1) * 6 / 8;
        for (int i=0;i<valiedSize;++i) data[dataSize++] = c3[i];
    }
    data.resize(dataSize);
    return data;
}

#endif //BASE3264_H

文章目录