From ddbe2f089e698cc928e2f0539a3ff0c13ae9ebec Mon Sep 17 00:00:00 2001 From: mrbesen Date: Mon, 5 Oct 2020 13:35:42 +0200 Subject: [PATCH] base64, 16 --- inc/util.h | 4 ++++ src/util.cpp | 53 +++++++++++++++++++++++++++++++++++++++++++++ tests/main.cpp | 3 ++- tests/utilstest.cpp | 21 ++++++++++++++++++ 4 files changed, 80 insertions(+), 1 deletion(-) diff --git a/inc/util.h b/inc/util.h index 117deea..875f6d0 100644 --- a/inc/util.h +++ b/inc/util.h @@ -26,6 +26,10 @@ unsigned int split(const std::string& str, const std::string& token, std::string void trim(std::string& str, char c = ' '); +std::string bytesToBase16(char* buffer, unsigned int len); +std::string bytesToBase64(char* buffer, unsigned int len); + + class StringSpliterator : public std::iterator { public: StringSpliterator(const std::string& d, const std::string& token); diff --git a/src/util.cpp b/src/util.cpp index fa3b49f..1060fd9 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -129,6 +129,59 @@ void mrbesen::Util::trim(std::string& str, char c) { str = str.substr(first, last-first); } +std::string mrbesen::Util::bytesToBase16(char* buffer, unsigned int len) { + static const char hexmap[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; + std::string s(len << 1, ' '); + for (unsigned int i = 0; i < len; ++i) { + s[ i<<1 ] = hexmap[(buffer[i] & 0xF0) >> 4]; + s[(i<<1) + 1] = hexmap[buffer[i] & 0x0F]; + } + return s; +} + +std::string mrbesen::Util::bytesToBase64(char* buffer, unsigned int len) { + //from: https://renenyffenegger.ch/notes/development/Base64/Encoding-and-decoding-base-64-with-cpp/index#cpp-base64-cpp + + 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 = '='; + static const char* base64_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"; + + 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; + } else { + uint8_t invmaskShift = 6 - maskShift; + nextb = (c & ~mask) << invmaskShift; + } + } + + 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; +} + + mrbesen::Util::StringSpliterator::StringSpliterator(const std::string& d, const std::string& token) : data(d), token(token) { //trim while(mrbesen::Util::removeStart(data, token)); diff --git a/tests/main.cpp b/tests/main.cpp index 757a3c4..29fb975 100644 --- a/tests/main.cpp +++ b/tests/main.cpp @@ -14,12 +14,13 @@ int testUtil_start_endWith(); int testUtil_removeStart_End(); int testUtil_insertStart_End(); int testUtil_trim(); +int testUtil_base(); int testStringSpliterator(); int testUtilSplit(); test_t tests[] = {testFiles_parent, testFiles_file, testFiles_extention, testFiles_scan, - testUtil_Count, testUtil_equalsIgnoreCase, testUtil_toLower, testUtil_start_endWith, testUtil_removeStart_End, testUtil_insertStart_End, testUtil_trim, + testUtil_Count, testUtil_equalsIgnoreCase, testUtil_toLower, testUtil_start_endWith, testUtil_removeStart_End, testUtil_insertStart_End, testUtil_trim, testUtil_base, testStringSpliterator, testUtilSplit, NULL}; diff --git a/tests/utilstest.cpp b/tests/utilstest.cpp index 181d1c8..75cc5cb 100644 --- a/tests/utilstest.cpp +++ b/tests/utilstest.cpp @@ -167,5 +167,26 @@ int testUtil_trim() { trim(a); ASSERT(a == "", a); + return TESTGOOD; +} + +int testUtil_base() { + char buf[] {0, (char) 0xAB, (char) 0x12, (char) 0xCD, (char) 0x34}; + + std::string ret = bytesToBase16(buf, 5); + ASSERT(ret == "00ab12cd34", ret); + + ret = bytesToBase64(buf, 5); + ASSERT(ret == "AKsSzTQ=", ret); + + ret = bytesToBase64(buf, 4); + ASSERT(ret == "AKsSzQ==", ret); + + ret = bytesToBase64(buf, 3); + ASSERT(ret == "AKsS", ret); + + ret = bytesToBase64(buf, 0); + ASSERT(ret == "", ret); + return TESTGOOD; } \ No newline at end of file