2009-12-28 4 views
9

Мне интересно, как преобразовать шестнадцатеричную строку в читаемую пользователем строку (если это имеет смысл), это будет моя первая реальная встреча с шестнадцатеричными значениями, поэтому я все еще узнаю о них и как управлять их.C++ Hex Parsing

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

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

+1

Чтобы уточнить: вы хотите взять двоичные данные и отобразить их в шестнадцатеричном формате? – James

+0

Я хочу взять необработанные пакетные данные, которые хранятся в шестнадцатеричном формате, и преобразовать их из шестнадцатеричного в удобочитаемый для человека формат. – Undawned

+0

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

ответ

3

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 из <cstdlib> делает это легко, если вы настаиваете на использовании класса шаблона для этого используйте зЬй :: stringstream для выполнения преобразование отдельных подстрок (например, «41») в десятичные значения (65).

+1

Я немного смущен, все, что кажется, это хранить шестеро в строку? Мне нужно преобразовать шестнадцатеричные данные в читаемую строку из его шестнадцатеричные данные, например http://home2.paulschou.net/tools/xlate/, этот вид веб-сайта. – Undawned

+0

Он дает шестнадцатеричное представление числа, справа , Что вы подразумеваете под «шестнадцатеричными данными»? Являются ли входные данные строкой с символами «414243», и вы хотите ее преобразовать, например. «ABC» (потому что это то, что делает сайт)? –

+0

Да, я хочу, чтобы преобразовать его в «ABC» это 1062000000000002000100024177616b656e65642d4465760036372e3232382e35302e3232333a38303835000000000009022c010000576f575472616e63652d4177616b656e696e670036372e3232382e34392e39303a3830383500000000000a содержит некоторые строки и IP-адрес сервера, я получил данные от, я хотел бы быть в состоянии преобразовать вышеуказанные данные в формат, который я могу читать значение он держится. – Undawned

0
fprintf(file, "%h", thing); 

Что-то вдоль этих линий?

0

Hex - это способ отображения двоичных данных. содержит строку, вы shoul d может видеть строку (возможно, среди других мусора), когда вы выводите ее на экран.

Вот цикл для печати символов 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

Это не ответ на вопрос, вы пытаетесь найти символы ASCII и отображать его. Почему вы выделяете буфер указателей при чтении символов? Почему вы пытаетесь присвоить адрес этого массива указателей указателю на char (не следует компилировать)? Почему вы используете вывод ошибки? – harper

+0

@ Харпер: Я предположил, что он был смущен природой двоичных данных и что на самом деле он не имел текстовых данных, закодированных как hex-in-ASCII. Чтобы напечатать текстовую часть некоторых данных, которые вы иначе просматриваете как шестую с какой-либо другой программой, вы пропустите символы, отличные от ASCII. Буфер указателей - это опечатка, должен быть простым буфером символов. Выход ошибки - это то, что я связываю подобные вещи с отладкой, и я использую 'cerr' для отладки, чтобы избежать вмешательства в« реальный »вывод программы. – Potatoswatter

11

Взято из библиотеки C++ String Toolkit Library (StrTk), должно быть достаточно. Обратите внимание, что out должен указывать на кусочек памяти наполовину размером как std :: distance (начало, конец) и что значения в диапазоне от [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; 
    }