From 5c09b782b970e9fecd192d5f34e56f3add0893ff Mon Sep 17 00:00:00 2001 From: Aadhavan Srinivasan Date: Sun, 4 Feb 2024 20:32:10 -0500 Subject: [PATCH] Added helper file for connect code --- includes/connect-helpers.hpp | 86 ++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 includes/connect-helpers.hpp diff --git a/includes/connect-helpers.hpp b/includes/connect-helpers.hpp new file mode 100644 index 0000000..f98daca --- /dev/null +++ b/includes/connect-helpers.hpp @@ -0,0 +1,86 @@ +#include +#include +#include +#include +#include +#include +namespace code { + namespace { /* Since these are internal function, I have wrapped them in an anonymous namespace, to prevent outside access to them */ + + /* Tokenizes a string, based on the given delimiter */ + std::vector tokenize_str(std::string str, std::string delim) { + std::vector result; + char* c_str = str.data(); + char* c_delim = delim.data(); + + char* tok = strtok(c_str, c_delim); + while (tok != NULL) { + result.push_back(std::string(tok)); + tok = strtok(NULL, c_delim); + } + + return result; + } + + /* Convert an IPv4 address from decimal to dotted decimal notation */ + std::string dec_to_dotted_dec(std::string addr) { + uint32_t addr_val = std::stoul(addr); /* 32 bit address */ + uint8_t addr_1 = (addr_val & (0xFF << 24)) >> 24; /* First octet (Bitwise AND the address with 255.0.0.0, and shift it to the right to obtain the first octet) */ + uint8_t addr_2 = (addr_val & (0xFF << 16)) >> 16; + uint8_t addr_3 = (addr_val & (0xFF << 8)) >> 8; + uint8_t addr_4 = (addr_val & 0xFF); + + std::string ret_val = std::string(std::to_string(addr_1) + "." + std::to_string(addr_2) + "." + std::to_string(addr_3) + "." + std::to_string(addr_4)); + + return ret_val; + } + + /* Convert an IPv4 address from dotted deecimal to decimal */ + std::string dotted_dec_to_dec(std::string addr) { + std::vector octets = tokenize_str(addr, "."); + uint32_t addr_val = (std::stoul(octets[0]) << 24) + (std::stoul(octets[1]) << 16) + (std::stoul(octets[2]) << 8) + (std::stoul(octets[3])); + return std::to_string(addr_val); + } + + } + + + /* Given an address and a port, return a 'code' which has the address and port encoded in it */ + std::string encode(std::string address, std::string port) { + /* Convert the address to decimal, and convert that to hex */ + std::string addr_coded = dotted_dec_to_dec(address); + std::stringstream stream; + stream << std::hex << std::stoul(addr_coded, 0, 10); + addr_coded = stream.str(); + + stream.str(""); + + /* Convert the port to hex */ + stream << std::hex << std::stoul(port, 0, 10); + std::string port_coded = stream.str(); + + std::string ret_val = addr_coded + "_" + port_coded; + + return ret_val; + + } + + /* Given a code, decode it and return a vector with the address and port */ + std::vector decode(std::string connect_code) { + std::vector result = tokenize_str(connect_code, "_"); /* Split the string into address and port */ + std::string address = result[0]; /* Address (in base 16) */ + std::string port = result[1]; /* Port (in base 16) */ + + /* Base 16 to base 10 - These lines convert the string to a base 10 number, and convert the result back into a string */ + address = std::to_string(std::stoul(address, 0, 16)); + port = std::to_string(std::stoul(address, 0, 10)); + + /* Convert decimal address to dotted decimal */ + address = dec_to_dotted_dec(address); + + std::vector ret_val; + ret_val.push_back(address); + ret_val.push_back(port); + return ret_val; + } +}