From 2a4db989d201af45d6e936f5b75e851348e52885 Mon Sep 17 00:00:00 2001 From: Nick Logozzo Date: Sun, 4 Feb 2024 18:23:38 -0500 Subject: [PATCH] StringHelpers - Base64 Encode and Decode --- .github/workflows/linux.yml | 4 ++-- .github/workflows/windows.yml | 4 ++-- CMakeLists.txt | 3 ++- README.md | 5 +++-- cmake/config.cmake.in | 1 + docs/helpers.md | 11 +++++++++++ include/helpers/stringhelpers.h | 12 ++++++++++++ src/helpers/stringhelpers.cpp | 23 +++++++++++++++++++++++ tests/stringtests.cpp | 15 +++++++++++++++ 9 files changed, 71 insertions(+), 7 deletions(-) diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 1695f3f..b17042f 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -47,10 +47,10 @@ jobs: uses: johnwason/vcpkg-action@v5 id: vcpkg with: - pkgs: boost-locale curl gettext-libintl glib gtest jsoncpp libsecret libuuid maddy openssl + pkgs: aklomp-base64 boost-locale curl gettext-libintl glib gtest jsoncpp libsecret libuuid maddy openssl triplet: x64-linux cache-key: ${{ matrix.config.os }} - revision: 4a2c30139309a6e4690ce929df33e85a1706a0e2 + revision: 80403036a665cb8fcc1a1b3e17593d20b03b2489 token: ${{ secrets.GITHUB_TOKEN }} - name: "Build" working-directory: ${{github.workspace}}/build diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 252623b..d3db6a8 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -34,10 +34,10 @@ jobs: uses: johnwason/vcpkg-action@v5 id: vcpkg with: - pkgs: boost-locale curl gettext-libintl gtest jsoncpp maddy openssl + pkgs: aklomp-base64 boost-locale curl gettext-libintl gtest jsoncpp maddy openssl triplet: x64-windows cache-key: ${{ matrix.config.os }} - revision: 4a2c30139309a6e4690ce929df33e85a1706a0e2 + revision: 80403036a665cb8fcc1a1b3e17593d20b03b2489 token: ${{ secrets.GITHUB_TOKEN }} - name: "Build" working-directory: ${{github.workspace}}/build diff --git a/CMakeLists.txt b/CMakeLists.txt index 5832824..8ea0a6a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -71,12 +71,13 @@ else() endif() #libnick Packages +find_package(base64 CONFIG REQUIRED) find_package(Boost REQUIRED COMPONENTS locale) find_package(CURL REQUIRED) find_package(jsoncpp CONFIG REQUIRED) find_package(Intl REQUIRED) find_package(OpenSSL REQUIRED) -target_link_libraries(${PROJECT_NAME} PUBLIC Boost::boost Boost::locale CURL::libcurl JsonCpp::JsonCpp Intl::Intl OpenSSL::SSL OpenSSL::Crypto) +target_link_libraries(${PROJECT_NAME} PUBLIC aklomp::base64 Boost::boost Boost::locale CURL::libcurl JsonCpp::JsonCpp Intl::Intl OpenSSL::SSL OpenSSL::Crypto) if(USING_VCPKG) find_package(unofficial-maddy CONFIG REQUIRED) target_link_libraries(${PROJECT_NAME} PUBLIC unofficial::maddy::maddy) diff --git a/README.md b/README.md index 004aa9c..1be6c16 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,7 @@ Documentation for this library and its modules can be found [here](/docs). The following are a list of dependencies used by libnick. ### All Platforms +- aklomp-base64 - boost - gtest - jsoncpp @@ -53,10 +54,10 @@ A C++20 compiler is also required to build libnick. 1. Set the `VCPKG_ROOT` environment variable to the path of your vcpkg installation's root directory. #### Windows 1. Set the `VCPKG_DEFAULT_TRIPLET` environment variable to `x64-windows` -1. Run `vcpkg install boost-locale curl gettext-libintl gtest jsoncpp maddy openssl` +1. Run `vcpkg install aklomp-base64 boost-locale curl gettext-libintl gtest jsoncpp maddy openssl` #### Linux 1. Set the `VCPKG_DEFAULT_TRIPLET` environment variable to `x64-linux` -1. Run `vcpkg install boost-locale curl gettext-libintl glib gtest jsoncpp libsecret libuuid maddy openssl` +1. Run `vcpkg install aklomp-base64 boost-locale curl gettext-libintl glib gtest jsoncpp libsecret libuuid maddy openssl` ### Building 1. First, clone/download the repo. diff --git a/cmake/config.cmake.in b/cmake/config.cmake.in index c6e7d90..60a90b2 100644 --- a/cmake/config.cmake.in +++ b/cmake/config.cmake.in @@ -10,6 +10,7 @@ if(DEFINED ENV{VCPKG_ROOT}) endif() endif() +find_dependency(base64 CONFIG REQUIRED) find_dependency(Boost REQUIRED COMPONENTS locale) find_dependency(CURL REQUIRED) find_dependency(jsoncpp CONFIG REQUIRED) diff --git a/docs/helpers.md b/docs/helpers.md index e2a9f8a..ed71d96 100644 --- a/docs/helpers.md +++ b/docs/helpers.md @@ -56,6 +56,17 @@ Path: `Nickvision::StringHelpers` - Returns: UINT_MAX if s as an unsigned int exceeds the bounds of an unsigned int. - Out: If idx != nullptr, the number of characters parsed will be stored in idx. - Ex: `StringHelpers::stoui("2837914")` will return `2837914`. +- ```cpp + std::string toBase64(const std::vector& bytes) + ``` + - Accepts: A list of bytes (char) + - Returns: The base64 encoded string of the bytes list. +- ```cpp + std::vector toByteList(const std::string& base64) + - Accepts: A base64 encoded string + - Returns: The list of bytes from the base64 encoded string. + - Returns: An empty list on error. + ``` - ```cpp std::string toLower(std::string s) ``` diff --git a/include/helpers/stringhelpers.h b/include/helpers/stringhelpers.h index 089f93c..3a19ad4 100644 --- a/include/helpers/stringhelpers.h +++ b/include/helpers/stringhelpers.h @@ -82,6 +82,18 @@ namespace Nickvision::StringHelpers * @return 0 if error */ unsigned int stoui(const std::string& s, size_t* idx = nullptr, int base = 10); + /** + * @brief Converts a list of bytes into a base64 encoded string. + * @param bytes The list of bytes + * @return The base64 encoded string of the bytes list + */ + std::string toBase64(const std::vector& bytes); + /** + * @brief Converts a base64 encoded string into a list of bytes. + * @param base64 The base64 encoded string + * @return The bytes list from the base64 encoded string, empty list if error + */ + std::vector toByteList(const std::string& base64); /** * @brief Gets a fully lowercase string from the provided string. * @param s The string to get lowercase diff --git a/src/helpers/stringhelpers.cpp b/src/helpers/stringhelpers.cpp index 3bf11c8..8436bfd 100644 --- a/src/helpers/stringhelpers.cpp +++ b/src/helpers/stringhelpers.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #ifdef _WIN32 #include @@ -132,6 +133,28 @@ namespace Nickvision } } + std::string StringHelpers::toBase64(const std::vector& bytes) + { + std::vector string; + size_t outSize{ 0 }; + string.resize(((4 * bytes.size() / 3) + 3) & ~3); + base64_encode(&bytes[0], bytes.size(), &string[0], &outSize, 0); + return { &string[0], outSize }; + } + + std::vector StringHelpers::toByteList(const std::string& base64) + { + std::vector bytes; + size_t outSize{ 0 }; + bytes.resize(3 * base64.size() / 4); + if(base64_decode(base64.c_str(), base64.size(), &bytes[0], &outSize, 0) == 1) + { + bytes.resize(outSize); + return bytes; + } + return {}; + } + std::string StringHelpers::toLower(std::string s) { std::transform(s.begin(), s.end(), s.begin(), [](unsigned char c) { return std::tolower(c); }); diff --git a/tests/stringtests.cpp b/tests/stringtests.cpp index 4400e7a..e5f184c 100644 --- a/tests/stringtests.cpp +++ b/tests/stringtests.cpp @@ -94,4 +94,19 @@ TEST(StringTests, Join3) TEST(StringTests, Replace1) { ASSERT_EQ(StringHelpers::replace("hello bye hi", "bye", "goodbye"), "hello goodbye hi"); +} + +TEST(StringTests, Base64) +{ + std::vector s{ 'A', 'B', 'X', 'J', 'K' }; + std::string base64; + ASSERT_NO_THROW(base64 = StringHelpers::toBase64(s)); + ASSERT_FALSE(base64.empty()); + std::vector bytes; + ASSERT_NO_THROW(bytes = StringHelpers::toByteList(base64)); + ASSERT_EQ(bytes.size(), s.size()); + for(size_t i = 0; i < bytes.size(); i++) + { + ASSERT_EQ(bytes[i], s[i]); + } } \ No newline at end of file