- 寫一個程序實現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);
}
};