2009-12-28 13 views
9

Mi chiedo come convertire una stringa esadecimale in una stringa leggibile dall'uomo (se questo ha senso) questo sarebbe il mio primo vero incontro con i valori esadecimali quindi sto ancora imparando su di loro e su come gestirlo loro.C++ Hex Parsing

Ho un programma che sta leggendo i dati da un file che contiene dati di pacchetto grezzi (hex) e ho bisogno di analizzare queste informazioni in modo che siano leggibili.

Un esempio di ciò che devo fare è qualcosa come questo sito http://home2.paulschou.net/tools/xlate/ in cui è possibile inserire in esadecimale e convertirlo in testo.

+1

Per chiarire: si desidera prendere dati binari e visualizzarli in formato esadecimale? – James

+0

Voglio prendere i dati di pacchetto grezzi che sono memorizzati in esadecimale e convertirli da esadecimale in un formato leggibile dall'uomo. – Undawned

+0

I dati grezzi sono essenzialmente binari, esadecimali è solo un modo più semplice per leggerli, poiché ogni quattro cifre binarie può essere letta come una singola cifra esadecimale. – phoebus

risposta

3

Il C++ - modo ish per ottenere una stringa contenente la rappresentazione esadecimale di un dato numero è quello di utilizzare il modificatore hex per i flussi, come in questo esempio:

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

È possibile utilizzare lo stesso modificatore su stringa flussi in caso è necessario avere la rappresentazione esadecimale in una variabile stringa:

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

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

UPDATE:

Se i dati di input vengono forniti come una stringa contenente la rappresentazione esadecimale dei caratteri di una stringa, è necessario conoscere la codifica della stringa di input per visualizzarla correttamente. Nel caso più semplice, la stringa è qualcosa come ASCII che mappa un byte in un carattere. Quindi, in un dato input "414243", ogni due caratteri ("41", "42", "43) mappano su un valore ASCII (65, 66, 67), che mappa su un carattere (" A "," B " ., "C")

Ecco come quella in 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" 

utilizzando std::strtol da <cstdlib> rende questo facile, se ti ostini a usare una classe template per questo, utilizzare std :: stringstream per eseguire la conversione delle singole sottostringhe (come "41") in valori decimali (65)

+1

Sono un po 'confuso, tutto ciò che sembra è archiviare l'esagono in una stringa? Ho bisogno di convertire i dati esadecimali in una stringa leggibile da i suoi dati esadecimali, come http://home2.paulschou.net/tools/xlate/ quel tipo di sito Web. – Undawned

+0

Fornisce la rappresentazione esadecimale di un numero, a destra . Cosa intendi con "dati esadecimali"? I dati di input sono una stringa con i caratteri "414243" e desideri convertirli in ad es. "ABC" (perché è così che funziona il sito Web)? –

+0

Sì voglio convertirlo in "ABC" questo 1062000000000002000100024177616b656e65642d4465760036372e3232382e35302e3232333a38303835000000000009022c010000576f575472616e63652d4177616b656e696e670036372e3232382e34392e39303a3830383500000000000a contiene alcune stringhe e un indirizzo IP del server ho ricevuto i dati da, mi piacerebbe essere in grado di convertire i dati di cui sopra in un formato che posso leggere i valori Tiene. – Undawned

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

Qualcosa di simile?

0

esadecimale è un modo di visualizzare dati binari, non è "dati grezzi" come dici tu. contiene una stringa, si spara d essere in grado di vedere la stringa (possibilmente tra gli altri rifiuti) quando la si trasmette allo schermo.

Ecco un ciclo per stampare i caratteri ASCII in un blocco di dati. Per ottenere qualcos'altro, dovrai affrontare il suo formato.

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

Questa non è una risposta alla domanda, si prova a trovare caratteri ASCII e visualizzarla. Perché assegni un buffer di puntatori quando leggi i caratteri? Perché provate ad assegnare l'indirizzo di questa matrice puntatore al puntatore char (non dovrebbe compilare)? Perché usi l'output dell'errore? – harper

+0

@Harper: presumevo che fosse confuso riguardo alla natura dei dati binari e che in realtà non disponesse di dati di testo codificati come hex-in-ASCII. Per stampare la parte di testo di alcuni dati che altrimenti stai visualizzando come esadecimale con altri programmi, salterai i caratteri non ASCII. Il buffer dei puntatori è un errore di battitura, dovrebbe essere un semplice buffer di caratteri. L'output dell'errore è perché associo questo tipo di cose con il debugging, e uso 'cerr' per il debug per evitare di interferire con l'output" reale "di un programma. – Potatoswatter

11

Scattato dalla libreria C++ String Toolkit Library (StrTk), quanto segue dovrebbe essere sufficiente. Nota che fuori dovrebbe puntare a un pezzo di memoria metà della dimensione di std :: distance (begin, end) e che i valori nell'intervallo di [begin, end) siano 0-9A-F o 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; 
    }