Last active
September 25, 2023 17:21
-
-
Save saulozitos/0a2719722b3d78c6d46aec8dec519515 to your computer and use it in GitHub Desktop.
Byte
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <iostream> | |
| #include <string> | |
| #include <stdexcept> | |
| #include <cstdint> | |
| #include <bitset> | |
| #include <sstream> | |
| #include <iomanip> | |
| #include <cctype> | |
| class Byte { | |
| private: | |
| uint8_t m_value; | |
| public: | |
| Byte(const std::string& value) { | |
| if (value.empty()) { | |
| throw std::invalid_argument("Valor de byte inválido."); | |
| } | |
| if (value.size() >= 2 && value[0] == '0' && (value[1] == 'x' || value[1] == 'X')) { | |
| // Valor hexadecimal (0x...) | |
| std::istringstream iss(value.substr(2)); | |
| iss >> std::hex >> m_value; | |
| } else if (value.size() == 2 && std::isxdigit(value[0]) && std::isxdigit(value[1])) { | |
| // Valor hexadecimal de dois dígitos (por exemplo, "FF") | |
| m_value = static_cast<uint8_t>(std::stoul(value, nullptr, 16)); | |
| } else if (value.size() > 2 && (value[0] == '0' && (value[1] == 'b' || value[1] == 'B'))) { | |
| // Valor binário (0b...) | |
| std::bitset<8> bits(value.substr(2)); | |
| m_value = static_cast<uint8_t>(bits.to_ulong()); | |
| } else { | |
| // Valor decimal | |
| m_value = static_cast<uint8_t>(std::stoi(value)); | |
| } | |
| } | |
| Byte(uint8_t value) : m_value(value) {} | |
| bool operator==(const Byte& other) const { | |
| return m_value == other.m_value; | |
| } | |
| bool operator!=(const Byte& other) const { | |
| return m_value != other.m_value; | |
| } | |
| Byte operator-(const Byte& other) const { | |
| return Byte(m_value - other.m_value); | |
| } | |
| Byte operator+(const Byte& other) const { | |
| return Byte(m_value + other.m_value); | |
| } | |
| Byte& operator<<=(int n) { | |
| m_value <<= n; | |
| return *this; | |
| } | |
| Byte& operator>>=(int n) { | |
| m_value >>= n; | |
| return *this; | |
| } | |
| Byte operator<<(int n) const { | |
| return Byte(m_value << n); | |
| } | |
| Byte operator>>(int n) const { | |
| return Byte(m_value >> n); | |
| } | |
| Byte& operator|=(const Byte& other) { | |
| m_value |= other.m_value; | |
| return *this; | |
| } | |
| Byte& operator&=(const Byte& other) { | |
| m_value &= other.m_value; | |
| return *this; | |
| } | |
| Byte& operator^=(const Byte& other) { | |
| m_value ^= other.m_value; | |
| return *this; | |
| } | |
| Byte operator|(const Byte& other) const { | |
| return Byte(m_value | other.m_value); | |
| } | |
| Byte operator&(const Byte& other) const { | |
| return Byte(m_value & other.m_value); | |
| } | |
| Byte operator^(const Byte& other) const { | |
| return Byte(m_value ^ other.m_value); | |
| } | |
| Byte operator~() const { | |
| return Byte(~m_value); | |
| } | |
| int toDecimal() const { | |
| return static_cast<int>(m_value); | |
| } | |
| std::string toHex() const { | |
| std::stringstream ss; | |
| ss << "0x" << std::uppercase << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(m_value); | |
| return ss.str(); | |
| } | |
| std::string toBin() const { | |
| return std::bitset<8>(m_value).to_string(); | |
| } | |
| }; | |
| class ByteArray { | |
| private: | |
| std::vector<Byte> m_data; | |
| public: | |
| ByteArray() = default; | |
| ByteArray(const std::vector<Byte>& data) : m_data(data) {} | |
| ByteArray(const std::string& hexString) { | |
| if (!isValidHexString(hexString)) { | |
| throw std::invalid_argument("String hexadecimal inválida."); | |
| } | |
| std::string sanitizedString = sanitizeHexString(hexString); | |
| for (size_t i = 0; i < sanitizedString.length(); i += 2) { | |
| std::string byteString = sanitizedString.substr(i, 2); | |
| m_data.emplace_back(byteString); | |
| } | |
| } | |
| void append(const std::vector<Byte> &bytes) { | |
| for(const auto & byte : bytes){ | |
| m_data.push_back(byte); | |
| } | |
| } | |
| std::string toHex() const { | |
| std::stringstream ss; | |
| for (const Byte& byte : m_data) { | |
| ss << byte.toHex() << ' '; | |
| } | |
| return ss.str(); | |
| } | |
| size_t size() const { | |
| return m_data.size(); | |
| } | |
| const Byte& operator[](size_t index) const { | |
| if (index >= m_data.size()) { | |
| throw std::out_of_range("Índice fora do alcance."); | |
| } | |
| return m_data[index]; | |
| } | |
| Byte& operator[](size_t index) { | |
| if (index >= m_data.size()) { | |
| throw std::out_of_range("Índice fora do alcance."); | |
| } | |
| return m_data[index]; | |
| } | |
| bool operator==(const ByteArray& other) const { | |
| return m_data == other.m_data; | |
| } | |
| private: | |
| static bool isValidHexString(const std::string& hexString) { | |
| // Verificar se a string contém apenas dígitos hexadecimais, espaços e "0x" ou "0X" | |
| for (char ch : hexString) { | |
| if (!isxdigit(ch) && ch != ' ' && ch != 'x' && ch != 'X') { | |
| return false; | |
| } | |
| } | |
| return true; | |
| } | |
| static std::string sanitizeHexString(const std::string& hexString) { | |
| // Remover espaços em branco e outros caracteres não hexadecimais da string | |
| const auto removePrefix =[&](const std::string &str, const std::string& prefix) { | |
| std::string out = str; | |
| size_t pos = 0; | |
| while ((pos = out.find(prefix, pos)) != std::string::npos) { | |
| out.erase(pos, prefix.length()); | |
| } | |
| return out; | |
| }; | |
| std::string sanitizedString = removePrefix(hexString, "0x"); | |
| sanitizedString = removePrefix(sanitizedString, "0X"); | |
| sanitizedString = removePrefix(sanitizedString, " "); | |
| return sanitizedString; | |
| } | |
| }; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
https://godbolt.org/z/4qa3avYo9