37#ifndef BASE64_UTILS_HPP
38#define BASE64_UTILS_HPP
46#if defined(_WIN64) || defined(WIN64) || defined(WIN32) || defined(_WIN32)
50#pragma comment(lib, "bcrypt")
51#pragma comment(lib, "crypt32")
65 template <
typename T =
char>
66 requires std::same_as<T, char> || std::same_as<T, wchar_t>
67 static std::basic_string<T>
urlEscape(
const std::basic_string<T>& src)
73 if constexpr (std::is_same_v<T, char>) {
74 std::ranges::for_each(encodeVal, [](T& ch) {
80 encodeVal.erase(std::remove(encodeVal.begin(), encodeVal.end(),
'\r'), encodeVal.end());
81 encodeVal.erase(std::remove(encodeVal.begin(), encodeVal.end(),
'\n'), encodeVal.end());
82 encodeVal.erase(std::remove(encodeVal.begin(), encodeVal.end(),
'='), encodeVal.end());
86 if constexpr (std::is_same_v<T, wchar_t>) {
87 std::ranges::for_each(encodeVal, [](T& ch) {
93 encodeVal.erase(std::remove(encodeVal.begin(), encodeVal.end(), L
'\r'), encodeVal.end());
94 encodeVal.erase(std::remove(encodeVal.begin(), encodeVal.end(), L
'\n'), encodeVal.end());
95 encodeVal.erase(std::remove(encodeVal.begin(), encodeVal.end(), L
'='), encodeVal.end());
110 template <
typename T =
char>
111 requires std::same_as<T, char> || std::same_as<T, wchar_t>
112 static std::basic_string<T>
encode(
const std::basic_string<T>& argBin)
121 if (!argBin.empty() &&
122 (TRUE == std::is_same_v<T, wchar_t> ? CryptBinaryToStringW((
const BYTE*)(argBin.data()),
123 static_cast<DWORD
>(argBin.length() *
sizeof(
wchar_t)),
124 CRYPT_STRING_BASE64 | CRYPT_STRING_NOCRLF,
127 : CryptBinaryToStringA((
const BYTE*)(argBin.data()),
128 static_cast<DWORD
>(argBin.length() *
sizeof(
char)),
129 CRYPT_STRING_BASE64 | CRYPT_STRING_NOCRLF,
133 std::vector<T> dest(
static_cast<size_t>(destSize) + 1);
135 if (TRUE == std::is_same_v<T, wchar_t> ? CryptBinaryToStringW((
const BYTE*)(argBin.data()),
136 static_cast<DWORD
>(argBin.length() *
sizeof(
wchar_t)),
137 CRYPT_STRING_BASE64 | CRYPT_STRING_NOCRLF,
140 : CryptBinaryToStringA((
const BYTE*)(argBin.data()),
141 static_cast<DWORD
>(argBin.length() *
sizeof(
char)),
142 CRYPT_STRING_BASE64 | CRYPT_STRING_NOCRLF,
146 return std::basic_string<T> {
reinterpret_cast<T*
>(dest.data()), destSize};
160 template <
typename T =
char>
161 requires std::same_as<T, char> || std::same_as<T, wchar_t>
162 static std::basic_string<T>
decode(
const std::basic_string<T>& textuallyEncoded)
166 if (textuallyEncoded.empty())
return {};
173 if (TRUE == std::is_same_v<wchar_t, T>
174 ? CryptStringToBinaryW(LPCWSTR(textuallyEncoded.c_str()),
175 static_cast<DWORD
>(textuallyEncoded.length()),
181 : CryptStringToBinaryA(LPCSTR(textuallyEncoded.c_str()),
182 static_cast<DWORD
>(textuallyEncoded.length()),
192 std::vector<T> dest(
static_cast<size_t>(destSize /
sizeof(T)) + 1);
194 if (TRUE == std::is_same_v<wchar_t, T> ? CryptStringToBinaryW(LPCWSTR(textuallyEncoded.c_str()),
195 static_cast<DWORD
>(textuallyEncoded.length()),
197 reinterpret_cast<BYTE*
>(dest.data()),
201 : CryptStringToBinaryA(LPCSTR(textuallyEncoded.c_str()),
202 static_cast<DWORD
>(textuallyEncoded.length()),
204 reinterpret_cast<BYTE*
>(dest.data()),
211 return std::basic_string<T> {
reinterpret_cast<T*
>(dest.data()), destSize /
sizeof(T)};
215 throw std::runtime_error(std::format(
"{} - CryptStringToBinary returned:{}", __func__, GetLastError()));
Base64 encode/decode functions.
static std::basic_string< T > encode(const std::basic_string< T > &argBin)
Base64 encode a given "binary" string and optionally url escape.
static std::basic_string< T > urlEscape(const std::basic_string< T > &src)
URL escape the base64 encoded string.
static std::basic_string< T > decode(const std::basic_string< T > &textuallyEncoded)
Base64 decode the given encoded string back to the binary value.