#c
#c
Вопрос:
Я хочу преобразовать строку, содержащую буквенно-цифровые символы, либо в uint32_t, либо в uint64_t. Попытался выполнить следующее. Но я получаю сообщение об ошибке «terminate вызывается после создания экземпляра ‘std:: out_of_range’ «. Кроме того, когда строка меньше по длине, например: string s = «hello», это работает, но что, если я хочу преобразовать более длинную строку в uint32_t или uint64_t.
#include <iostream>
#include <sstream>
#include <iomanip>
std::string string_to_hex(const std::stringamp; in) {
std::stringstream ss;
ss << std::hex << std::setfill('0');
for (size_t i = 0; i < in.size(); i) {
ss << std::setw(2) << static_cast<unsigned int>(static_cast<unsigned char>(in[i]));
}
return ss.str();
}
int main() {
std::string s = "hello world, this 123";
std::string hex_str = string_to_hex(s);
uint32_t value = std::stoul(hex_str , nullptr, 16);
cout<<value<<endl;
}
Итак, согласно приведенным комментариям, является ли следующий лучший способ сделать это?
int main()
{
std::string s = "hello world, this 123";
std::hash<std::string> hashed_name;
uint32_t value = hashed_name(s);
cout<<value<<endl;
return 0;
}
Комментарии:
1. В вашем примере input string создается шестнадцатеричная строка
"68656c6c6f20776f726c642c207468697320313233"
, которая СЛИШКОМ ВЕЛИКАstoul()
, чтобы вписаться как есть в anunsigned long
. Похоже, вы пытаетесь преобразовать входную строку в число. Использование промежуточной шестнадцатеричной строки не является способом достижения этой цели. Hex — это просто способ представления двоичных данных в удобочитаемом формате. Это не изменяет сами данные. Вместо этого вам нужен реальный алгоритм хэширования, такой как CRC, MD5, SHA и т. Д. Они принимают произвольные данные в качестве входных данных и математически преобразуют их в числа фиксированной ширины в качестве выходных данных.2. Сделайте себе одолжение и непосредственно
std::cout << hex_str << 'n';
перед попыткой этого преобразования. Теперь посмотрите на эту вещь и спросите себя, есть ли шанс, что это превратится в платформу без знака длиной (которая обычно составляет 32 бита на x86, 64 бита на x64). Для предоставленных вами примеров данных68656c6c6f20776f726c642c207468697320313233
будет источником преобразования, который преобразуется в152575196276689931390365168237947948156825094926899
десятичный. Это никак не вписывается ни в 32-битное, ни в 64-битное значение.3. Что вы собираетесь делать с этим числом? Вы когда-нибудь хотели преобразовать ее обратно в исходную строку?
4. @Vlad Feinstein, да, возможно, мне тоже придется это сделать.
5. Тогда о хешировании не может быть и речи (оно выполняется только в одну сторону). Снова,
What are you going to do with that number?
Ответ №1:
Это, строго говоря, делает то, что вам нужно:
#include <iostream>
#include <string>
#include <unordered_map>
class Converter
{
public:
static int StringToInt(const std::stringamp; s)
{
auto it = cache.find(s);
if (it != cache.end())
return it->second;
cache[s] = count;
lookup[count ] = s;
}
static std::string IntToString(unsigned i)
{
auto it = lookup.find(i);
if (it != lookup.end())
return it->second;
return "";
}
private:
static inline unsigned count = 0;
static inline std::unordered_map<std::string, int> cache;
static inline std::unordered_map<int, std::string> lookup;
};
int main() {
std::string s = "hello world, this 123";
int value = Converter::StringToInt(s);
std::cout << value << std::endl;
std::string s2 = Converter::IntToString(value);
std::cout << s2 << std::endl;
int value2 = Converter::StringToInt("hello world, this 123");
std::cout << value2 << std::endl;
}
Ответ №2:
Ваша проблема в том, что результирующее hex_str
значение является ОГРОМНЫМ числом. В частности: 0x68656c6c6f20776f726c642c207468697320313233
Вы преобразуете каждый символ в двузначное шестнадцатеричное значение (т.Е. В один байт). Строки размером 4 (8, если используется 64-разрядный int) или более приведут к слишком большому числу, чтобы вписаться в ваш результирующий uint32_t
или uint64_t
Посмотрите эту распечатку GDB вашей программы
Как упоминал Реми в комментариях, изучите алгоритмы хэширования.