Я работаю со старой программой и нуждаюсь в помощи, заменяющей порядок Hex String.
Да, строка... как в:
string hexString = "F07D0079"
string hexString2= "F07F"
Мне нужно, чтобы каждая строка выглядела так: 79007DF0 и 7FF0 соответственно.
Для любви к Богу я не знаю, почему они хранятся в строках, но они есть.
Это небольшая проблема с endian/big endian, но поскольку она в строке я не могу использовать стандартные функции для изменения порядка, могу ли я?
Есть ли простой способ сделать это?
std::string swapValues(string originalHex)
{
string swappedHex;
//what to do here.
return swappedHex;
}
Я могу использовать функцию-член append
.
std::string reverse_pairs(std::string const & src)
{
assert(src.size() % 2 == 0);
std::string result;
result.reserve(src.size());
for (std::size_t i = src.size(); i != 0; i -= 2)
{
result.append(src, i - 2, 2);
}
return result;
}
(В качестве упражнения в расширяемости вы также можете сделать параметр " 2
").
Если вы хотите сделать это на месте, вы можете использовать std::rotate
в цикле.
Сначала проверьте, что длина четная (если она еще не была дезинфицирована):
assert(hex.length() % 2 == 0);
Затем измените строку:
std::reverse(hex.begin(), hex.end());
Теперь байты находятся в правильном порядке, но цифры внутри каждого из них ошибочны, поэтому нам нужно их поменять:
for (auto it = hex.begin(); it != hex.end(); it += 2) {
std::swap(it[0], it[1]);
}
it[0]
вызывает проблемы? Кто говорит, что существует? Почему std::iter_swap
вместо этого не использовать std::iter_swap
?
*(it+0)
. Вы можете использовать iter_swap
или другие альтернативы, если это не подходит для вашей эстетики.
Я бы не стал беспокоиться о чем-то слишком умном для этого:
std::string swapValues(const std::string& o)
{
std::string s(o.length());
if (s.length() == 4) {
s[0] = o[2];
s[1] = o[3];
s[2] = o[0];
s[3] = o[1];
return s;
}
if (s.length() == 8) {
// left as an exercise
}
throw std::logic_error("You got to be kidding me...");
}
Должны быть доступны библиотечные функции (наивное манипулирование строками может быть бесполезным):
#include <iostream>
#include <arpa/inet.h>
int main() {
std::string hex32 = "F07D0079";
std::string hex16 = "F07F";
std::uint32_t u32 = std::strtoul(hex32.c_str(), 0, 16);
std::uint16_t u16 = std::strtoul(hex16.c_str(), 0, 16);
// Here we would need to know the endian of the sources.
u32 = ntohl(u32);
u16 = ntohs(u16);
std::cout << std::hex << u32 << ", " << u16 << '\n';
}
Linux/Little Endian
Любая функция, действующая на строки, должна знать целевую платформу (следовательно, нет общего решения)
ntohl
и ntohs
являются частью вашей библиотеки компилятора.