- 写一个程序实现base32的编码与解码。base32编码的原理:对于任意一个二进制字节数组,将连续的5个bit进行编码,5个bit可以表示32个不同的数,分别映射到a-z(26个字母)和 0-5(6个数字),比如00000映射到a,00001映射到b,00010映射到c,...,11110映射到4,11111映射到5。这样任意的二进制字节都可以用这32个字符编码。如果字节数组长度不是5的整数倍。需要在末位进行补充0.
- 比如对于字符数组“ABC”,ASCII表中A对应的数据是65,B是66,C是67。整个字符数组的二进制编码是01000001 01000010 01000011。按照5个一组进行末尾补0,变成01000 00101 00001 00100 00110 对应的base32的编码是ifbeg。写一个base32对应的编码和解码功能,如果解码函数输入不是合法的base32编码,抛出异常。
#include <iostream>
#include <vector>
typedef unsigned char byte;
class Base32Utils {
private:
static byte encode_idx(int c){
return c < 26 ? c + 'a' : c - 26 + '0';
}
static int decode_idx(byte c){
if(c <= '5' && c >= '0') return c - '0' + 26;
if(c <= 'z' && c >= 'a') return c - 'a';
throw 100;
}
static std::vector<byte> code(std::vector<byte> &data, int _cnt, int _pos, bool is_decode){
std::vector<byte> ans;
int val, i = 0, cnt, num, pos = -1;
while(i < data.size()){
cnt = _cnt, val = 0;
while((!is_decode || i < data.size()) && cnt--){
if(pos == -1){
pos = _pos;
num = is_decode ? decode_idx(data[i++]) : data[i++];
}
val |= (num>>pos--&1)<<cnt;
}
ans.push_back(is_decode ? val : encode_idx(val));
}
if(is_decode){
if(cnt <= pos + 1){
while(cnt--) *ans.rbegin() |= (num>>pos--&1)<<cnt;
if(~pos && num&(1<<pos)-1) throw 100;
}
else {
if(ans.back() || num&(1<<pos)-1) throw 100;
ans.pop_back();
}
}
else {
while(~pos){
val = 0, cnt = 5;
while(cnt-- && ~pos) val |= (num>>pos--&1)<<cnt;
ans.push_back(encode_idx(val));
}
}
return ans;
}
public:
static std::vector<byte> encode(std::vector<byte> data){
return code(data, 5, 7, false);
}
static std::vector<byte> decode(std::vector<byte> data){
return code(data, 8, 4, true);
}
};