Шестнадцатеричный парсинг C++

Я задаюсь вопросом, как преобразовать шестнадцатеричную строку в человекочитаемую строку (если бы это имеет какой-либо смысл), это было бы моим первым реальным обнаружением с шестнадцатеричными значениями, таким образом, я все еще узнаю о них и как управлять ими.

У меня есть программа, которая читает в данных из файла, который содержит необработанные пакетные данные (шестнадцатеричное число), и я должен проанализировать эту информацию, таким образом, это человекочитаемо.

Пример того, что я должен сделать, является чем-то вроде этого, что сайт делает http://home2.paulschou.net/tools/xlate/, где можно вставить шестнадцатеричное число и иметь преобразованный в текст.

10
задан Undawned 28 December 2009 в 00:50
поделиться

4 ответа

Способ получения строки, содержащей шестнадцатеричное представление заданного числа на языке C++, заключается в использовании модификатора hex для потоков, как в данном примере:

const int i = 0xdeadbeef;
cout << "0x" << hex << i << endl; // prints "0xdeadbeef"

Вы можете использовать тот же модификатор для потоков строк в случае, если вам необходимо шестнадцатеричное представление в строковой переменной:

const int i = 0xdeadc0de;
ostringstream stream;
stream << "0x" << hex << i;

const string s = stream.str(); // s now contains "0xdeadc0de"

UPDATE:

Если входные данные даются в виде строки, содержащей шестнадцатеричное представление символов строки, то для корректного отображения необходимо знать кодировку входной строки. В простейшем случае строка представляет собой нечто вроде ASCII, который сопоставляет один байт с одним символом. Так в заданном вводе "414243" каждые два символа ("41", "42", "43") отображаются в ASCII значение (65, 66, 67), которое отображается в символ ("A", "B", "C").

Вот как это сделать на C++:

const string hexData = "414243";

assert( hexData.size() % 2 == 0 );

ostringstream asciiStream;
istringstream hexDataStream( hexData );
vector<char> buf( 3 ); // two chars for the hex char, one for trailing zero
while ( hexDataStream.good() ) {
    hexDataStream.get( &buf[0], buf.size() );
    if ( hexDataStream.good() ) {
        asciiStream << static_cast<char>( std::strtol( &buf[0], 0, 16 ) );
    }
}

const string asciiData = asciiStream.str(); // asciiData == "ABC"

Использование std::strtol из делает это простым; если вы настаиваете на использовании шаблонного класса для этого, используйте std::stringstream для преобразования одиночных подстрок (например, "41") в десятичные значения (65).

.
3
ответ дан 3 December 2019 в 22:37
поделиться

Гекс - это способ отображения двоичных данных. Это не "сырые данные", как вы говорите. Если исходные данные, которые у вас есть, содержат строку, вы должны быть в состоянии увидеть строку (возможно, среди прочего мусора), когда вы выводите ее на экран.

Вот цикл для вывода ASCII-символов в блоке данных. Чтобы получить что-то ещё, Вам придётся иметь дело с его форматом.

char *binary_data[ BUFFER_SIZE ];
size_t len = BUFFER_SIZE;
len = get_a_packet( data, len ); // or however you get data

for ( char *text_ptr = binary_data; text_ptr != binary_data + len; ++ text_ptr ) {
    if ( * text_ptr <= '~' && * text_ptr >= ' ' ) { // if it's ascii
        cerr << * text_ptr; // print it out
    }
}

cerr << endl;
0
ответ дан 3 December 2019 в 22:37
поделиться
fprintf(file, "%h", thing);

Что-то в этом роде?

0
ответ дан 3 December 2019 в 22:37
поделиться

Взято из библиотеки C++ String Toolkit Library (StrTk), должно быть достаточно следующего. Обратите внимание, что out должно указывать на кусок памяти вдвое меньше размера как std::distance(begin,end), и что значения в диапазоне [begin,end] должны быть 0-9A-F или 0-9a-f

inline bool convert_hex_to_bin(const unsigned char* begin, 
                               const unsigned char* end, 
                               unsigned char* out)
    {
       if (std::distance(begin,end) % 2)
          return false;
       static const std::size_t symbol_count = 256;
       static const unsigned char hex_to_bin[symbol_count] = {
                    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x00 - 0x07
                    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x08 - 0x0F
                    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x10 - 0x17
                    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x18 - 0x1F
                    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x20 - 0x27
                    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x28 - 0x2F
                    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, // 0x30 - 0x37
                    0x08, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x38 - 0x3F
                    0x00, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x00, // 0x40 - 0x47
                    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x48 - 0x4F
                    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x50 - 0x57
                    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x58 - 0x5F
                    0x00, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x00, // 0x60 - 0x67
                    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x68 - 0x6F
                    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x70 - 0x77
                    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x78 - 0x7F
                    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x80 - 0x87
                    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x88 - 0x8F
                    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x90 - 0x97
                    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x98 - 0x9F
                    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xA0 - 0xA7
                    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xA8 - 0xAF
                    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xB0 - 0xB7
                    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xB8 - 0xBF
                    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xC0 - 0xC7
                    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xC8 - 0xCF
                    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xD0 - 0xD7
                    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xD8 - 0xDF
                    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xE0 - 0xE7
                    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xE8 - 0xEF
                    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xF0 - 0xF7
                    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00  // 0xF8 - 0xFF
                  };

       const unsigned char* itr = begin;
       while (end != itr)
       {
          (*out)  = static_cast<unsigned char>(hex_to_bin[*(itr++)] << 4);
          (*out) |= static_cast<unsigned char>(hex_to_bin[*(itr++)]     );
          ++out;
       }
       return true;
    }
12
ответ дан 3 December 2019 в 22:37
поделиться
Другие вопросы по тегам:

Похожие вопросы: