From 478af5f01eca9e3ffdd05988943fabf46e187f2c Mon Sep 17 00:00:00 2001 From: James Turner Date: Sun, 9 Jun 2013 19:17:37 +0100 Subject: [PATCH] Base64 and hex helpers for strings --- simgear/misc/strutils.cxx | 94 ++++++++++++++++++++++++++++++++++++++- simgear/misc/strutils.hxx | 13 ++++++ 2 files changed, 106 insertions(+), 1 deletion(-) diff --git a/simgear/misc/strutils.cxx b/simgear/misc/strutils.cxx index c6687158..d064ed6b 100644 --- a/simgear/misc/strutils.cxx +++ b/simgear/misc/strutils.cxx @@ -334,6 +334,98 @@ std::string convertWindowsLocal8BitToUtf8(const std::string& a) #endif } - } // end namespace strutils +static const std::string base64_chars = +"ABCDEFGHIJKLMNOPQRSTUVWXYZ" +"abcdefghijklmnopqrstuvwxyz" +"0123456789+/"; + + +static inline bool is_base64(unsigned char c) { + return (isalnum(c) || (c == '+') || (c == '/')); +} + +static bool is_whitespace(unsigned char c) { + return ((c == ' ') || (c == '\r') || (c == '\n')); +} + +std::string decodeBase64(const std::string& encoded_string) +{ + int in_len = encoded_string.size(); + int i = 0; + int j = 0; + int in_ = 0; + unsigned char char_array_4[4], char_array_3[3]; + std::string ret; + + while (in_len-- && ( encoded_string[in_] != '=')) { + if (is_whitespace( encoded_string[in_])) { + in_++; + continue; + } + + if (!is_base64(encoded_string[in_])) { + break; + } + + char_array_4[i++] = encoded_string[in_]; in_++; + if (i ==4) { + for (i = 0; i <4; i++) + char_array_4[i] = base64_chars.find(char_array_4[i]); + + char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4); + char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2); + char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3]; + + for (i = 0; (i < 3); i++) + ret += char_array_3[i]; + i = 0; + } + } + + if (i) { + for (j = i; j <4; j++) + char_array_4[j] = 0; + + for (j = 0; j <4; j++) + char_array_4[j] = base64_chars.find(char_array_4[j]); + + char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4); + char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2); + char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3]; + + for (j = 0; (j < i - 1); j++) ret += char_array_3[j]; + } + + return ret; +} + +const char hexChar[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; + +std::string encodeHex(const std::string& bytes) +{ + std::string hex; + size_t count = bytes.size(); + for (unsigned int i=0; i> 4]); + hex.push_back(hexChar[c & 0x0f]); + } + + return hex; +} + +std::string encodeHex(const unsigned char* rawBytes, unsigned int length) +{ + std::string hex; + for (unsigned int i=0; i> 4]); + hex.push_back(hexChar[c & 0x0f]); + } + + return hex; +} + +} // end namespace strutils } // end namespace simgear diff --git a/simgear/misc/strutils.hxx b/simgear/misc/strutils.hxx index c9aa525c..d2c8a3e8 100644 --- a/simgear/misc/strutils.hxx +++ b/simgear/misc/strutils.hxx @@ -155,6 +155,19 @@ namespace simgear { */ std::string convertWindowsLocal8BitToUtf8(const std::string& a); + /** + * convert base-64 encoded data to raw bytes (possibly with embedded + * NULs). Throws an exception if input data is not base64, or is + * malformed + */ + std::string decodeBase64(const std::string& a); + + /** + * convert bytes to hexadecimal equivalent + */ + std::string encodeHex(const std::string& bytes); + + std::string encodeHex(const unsigned char* rawBytes, unsigned int length); } // end namespace strutils } // end namespace simgear -- 2.39.5