diff --git a/src/util.cpp b/src/util.cpp index 1060fd9..2b1bfc4 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -144,8 +144,6 @@ std::string mrbesen::Util::bytesToBase64(char* buffer, unsigned int len) { if(len == 0) return ""; - const uint8_t overlen = len % 3; - const uint8_t len_padding = overlen ? (3 - overlen) : 0; //anzahl benötigter padding chars size_t len_encoded = (len+2) / 3 * 4; static const unsigned char trailing_char = '='; @@ -154,30 +152,24 @@ std::string mrbesen::Util::bytesToBase64(char* buffer, unsigned int len) { std::string ret; ret.reserve(len_encoded); - char nextb = 0; - for(unsigned int pos = 0; pos < len; pos ++) { - const char c = buffer[pos]; - uint8_t tripos = pos % 3; //position im trible - uint8_t maskShift = (1+tripos) << 1; //2, 4, 6 - uint8_t mask = 0xff << maskShift; - ret.push_back(base64_chars[((c & mask) >> maskShift) | nextb]); - - if(tripos == 2) { - ret.push_back(base64_chars[c & ~mask]); - nextb = 0; + for(unsigned int pos = 0; pos < len; pos += 3) { + ret.push_back(base64_chars[(buffer[pos] & 0xfc) >> 2]); + if (pos+1 < len) { + ret.push_back(base64_chars[((buffer[pos] & 0x03) << 4) + ((buffer[pos + 1] & 0xf0) >> 4)]); + if (pos+2 < len) { + ret.push_back(base64_chars[((buffer[pos + 1] & 0x0f) << 2) + ((buffer[pos + 2] & 0xc0) >> 6)]); + ret.push_back(base64_chars[ buffer[pos + 2] & 0x3f]); + } else { + ret.push_back(base64_chars[(buffer[pos + 1] & 0x0f) << 2]); + ret.push_back(trailing_char); + } } else { - uint8_t invmaskShift = 6 - maskShift; - nextb = (c & ~mask) << invmaskShift; + ret.push_back(base64_chars[(buffer[pos] & 0x03) << 4]); + ret.push_back(trailing_char); + ret.push_back(trailing_char); } } - if(nextb) - ret.push_back(base64_chars[(int) nextb]); - - for(uint8_t i = 0; i < len_padding; ++i) { - ret.push_back(trailing_char); - } - return ret; } diff --git a/tests/utilstest.cpp b/tests/utilstest.cpp index 75cc5cb..1750d3e 100644 --- a/tests/utilstest.cpp +++ b/tests/utilstest.cpp @@ -171,7 +171,7 @@ int testUtil_trim() { } int testUtil_base() { - char buf[] {0, (char) 0xAB, (char) 0x12, (char) 0xCD, (char) 0x34}; + char buf[] {0, (char) 0xAB, (char) 0x12, (char) 0xCD, (char) 0x34, (char) 0xFF}; std::string ret = bytesToBase16(buf, 5); ASSERT(ret == "00ab12cd34", ret); @@ -188,5 +188,8 @@ int testUtil_base() { ret = bytesToBase64(buf, 0); ASSERT(ret == "", ret); + ret = bytesToBase64(buf, 6); + ASSERT(ret == "AKsSzTT_", ret); + return TESTGOOD; } \ No newline at end of file