├── .gitignore ├── src ├── myBase64.h └── myBase64.cpp ├── makefile └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | /out/ -------------------------------------------------------------------------------- /src/myBase64.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | class myBase64 { 4 | private: 5 | static char DC[64]; 6 | static int CD[128]; 7 | static char digit2Char(int n); 8 | static int char2Digit(char c); 9 | 10 | public: 11 | static std::string encode(const std::string & s); 12 | static std::string decode(const std::string & s); 13 | }; 14 | -------------------------------------------------------------------------------- /makefile: -------------------------------------------------------------------------------- 1 | .PHONY : help 2 | help : 3 | @echo " all build libmyBase64.o in ./out/" 4 | @echo " clean remove direcoty and content in ./out/" 5 | 6 | ./out/myBase64.o : ./src/myBase64.cpp 7 | [ -d ./out/ ] || mkdir ./out/ 8 | g++ -c ./src/myBase64.cpp -o ./out/myBase64.o 9 | 10 | ./out/libmyBase64.a : ./out/myBase64.o 11 | ar -r ./out/libmyBase64.a ./out/myBase64.o 12 | 13 | .PHONY : all 14 | all : ./out/libmyBase64.a 15 | 16 | .PHONY : clean 17 | clean : 18 | rm -rf ./out/ 19 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # myBase64 2 | 3 | 个人实现的一个Base64编解码轮子 4 | 5 | ## 使用 6 | 7 | ### 生成静态链接库 8 | 9 | 使用命令行则是与配置好的`task`相同的效果, 终归`task`也只是命令行的一种便捷方式罢了, 具体命令如下: 10 | 11 | ``` 12 | mkdir -p ./out 13 | g++ -c ./src/myBase64.cpp -o ./out/myBase64.o 14 | ar -r ./out/libmyBase64.a ./out/myBase64.o 15 | ``` 16 | 17 | 另外可以使用`make`来构建, 效果和命令行构建是一样的, 或者说是只不过是把命令行的命令照搬进`makefile`里面了. 18 | 19 | ``` 20 | make all 21 | ``` 22 | 23 | ### 在其他项目中使用 24 | 25 | 把此项目中的`myBase64.h`头文件和生成的`libmyBase64.a`拷走, 包含在你自己的项目中, 然后在编译的时候使用以下命令即可编译. 26 | 27 | 其中`lib`是静态链接库的目录, `myBase64`是生成的静态链接库(默认指定静态链接库名称后, 编译器会在名称前加上`lib`, 在加上后缀`.a`后寻找静态链接库文件) 28 | 29 | ``` 30 | # 注意静态链接库的参数要放在最后面 31 | g++ {your cpp files} -Llib -lmyBase64 32 | ``` 33 | 34 | ## 注意事项 35 | 36 | 目前仅支持字符串编解码, 同时并未处理文本编码, 所以在对如汉字等非ASCII码的字符串编码时, 在不同的系统中有可能会出现与通用编解码不同的结果. 37 | 38 | ## 基于注意事项的建议 39 | 40 | 1. 尽可能编解码英文 41 | 2. 不要解码太长的东西 42 | 43 | ## 许可证 44 | 45 | 1. 可随意使用, 不限制使用范围. 46 | 2. 可不署名原作者(好挫的代码署名丢人`>﹏<`) 47 | 3. 造成的一切后果与原作者无关. 48 | -------------------------------------------------------------------------------- /src/myBase64.cpp: -------------------------------------------------------------------------------- 1 | #include "myBase64.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | char myBase64::DC[64] = { 8 | 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 9 | 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 10 | 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 11 | 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 12 | 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 13 | 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', 14 | '8', '9', '+', '/' 15 | }; 16 | 17 | int myBase64::CD[128] = { 18 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, 0, 63, 52, 53, 21 | 54, 55, 56, 57, 58, 59, 60, 61, 0, 0, 0, 0, 0, 0, 22 | 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 23 | 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 0, 0, 0, 24 | 0, 0, 0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 25 | 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 26 | 50, 51, 0, 0, 0, 0, 0, 27 | }; 28 | 29 | 30 | char myBase64::digit2Char(int n) { 31 | return DC[n]; 32 | } 33 | 34 | int myBase64::char2Digit(char c) { 35 | if (c == '=') 36 | return 0; 37 | return CD[c]; 38 | } 39 | 40 | std::string myBase64::encode(const std::string & str) { 41 | // a & 0xFC >> 2 42 | // a & 0x03 << 4 + b & 0xF0 >> 4 43 | // b & 0x0F << 2 + c & 0xC0 >> 6 44 | // c & 0x3F 45 | 46 | unsigned len = str.size(); 47 | unsigned tmpLen = (len / 3 + (len % 3 > 0)) * 3; 48 | char * tmpStr = new char[tmpLen]; 49 | std::memset(tmpStr, 0, tmpLen); 50 | for (int i = 0; i < len; ++i) 51 | tmpStr[i] = str[i]; 52 | 53 | std::string result; 54 | uint8_t * unit = (uint8_t*)tmpStr; 55 | unsigned cnt = tmpLen / 3; 56 | 57 | for (int i = 0; i < cnt; ++i, unit += 3) { 58 | result += digit2Char((unit[0] & 0xFC) >> 2); 59 | result += digit2Char(((unit[0] & 0x03) << 4) + ((unit[1] & 0xF0) >> 4)); 60 | result += digit2Char(((unit[1] & 0x0F) << 2) + ((unit[2] & 0xC0) >> 6)); 61 | result += digit2Char(unit[2] & 0x3F); 62 | } 63 | 64 | uint8_t amountMissing = (len % 3 == 0) ? 0 : 3 - len % 3; 65 | for (uint8_t i = 0; i < amountMissing; ++i) 66 | result[result.size() - 1 - i] = '='; 67 | 68 | delete [] tmpStr; 69 | return result; 70 | } 71 | 72 | std::string myBase64::decode(const std::string & str) { 73 | // a = (A << 2) + ((B & 0x30) >> 4); 74 | // b = ((B & 0x0F) << 4) + ((C & 0x3C) >> 2) 75 | // c = ((C & 0x03) << 6) + (D & 0x3F) 76 | 77 | std::string result; 78 | const char * s = str.c_str(); 79 | unsigned len = str.size(); 80 | for (int i = 0; i < len; i += 4, s += 4) { 81 | int A, B, C, D; 82 | A = char2Digit(s[0]), B = char2Digit(s[1]); 83 | C = char2Digit(s[2]), D = char2Digit(s[3]); 84 | 85 | result += (A << 2) + ((B & 0x30) >> 4); 86 | result += ((B & 0x0F) << 4) + ((C & 0x3C) >> 2); 87 | result += ((C & 0x03) << 6) + (D & 0x3F); 88 | } 89 | 90 | if (str[len - 2] == '=') { 91 | result = result.substr(0, result.size() - 2); 92 | } else if (str[len - 1] == '=') { 93 | result = result.substr(0, result.size() - 1); 94 | } 95 | 96 | return result; 97 | } 98 | --------------------------------------------------------------------------------