Skip to content

Instantly share code, notes, and snippets.

@saulozitos
Last active September 25, 2023 17:21
Show Gist options
  • Save saulozitos/0a2719722b3d78c6d46aec8dec519515 to your computer and use it in GitHub Desktop.
Save saulozitos/0a2719722b3d78c6d46aec8dec519515 to your computer and use it in GitHub Desktop.
Byte
#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;
}
};
@saulozitos
Copy link
Author

saulozitos commented Sep 25, 2023

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment