简体   繁体   English

C ++ Hex Parsing

[英]C++ Hex Parsing

I'm wondering how to convert a hex string to a human readable string (if that makes any sense) this would be my first real encounter with hex values so I'm still learning about them and how to manage them. 我想知道如何将十六进制字符串转换为人类可读的字符串(如果这有意义)这将是我第一次真正遇到十六进制值,所以我仍然在学习它们以及如何管理它们。

I have a program which is reading in data from a file which contains raw packet data (hex) and I need to parse this information so it's human readable. 我有一个程序,它从包含原始数据包数据(十六进制)的文件读取数据,我需要解析这些信息,因此它是人类可读的。

An example of what I need to do is something like this site does http://home2.paulschou.net/tools/xlate/ where you can put in hex and have it converted to text. 我需要做的一个例子是像这个网站http://home2.paulschou.net/tools/xlate/这样你可以放入十六进制并将其转换为文本。

Taken from the C++ String Toolkit Library (StrTk) library, the following should suffice. C ++ String Toolkit Library(StrTk)库中获取以下内容就足够了。 Note that out should point to a piece of memory half the size of as std::distance(begin,end), and that the values in the range of [begin,end) be 0-9A-F or 0-9a-f 请注意,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;
    }

The C++-ish way to get a string containing the hexadecimal representation of a given number is to use the hex modifier for streams, as in this example: C ++ - 获取包含给定数字的十六进制表示的字符串的方法是对流使用hex修饰符,如下例所示:

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

You can use the same modifier on string streams in case you need to have the hexadecimal representation in a string variable: 如果需要在字符串变量中使用十六进制表示,则可以对字符串流使用相同的修饰符:

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

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

UPDATE: 更新:

If your input data is given as a string containing the hexadecimal representation of the characters of a string, you will need to know the encoding of the input string in order to display it correctly. 如果输入数据是以包含字符串字符的十六进制表示形式的字符串形式给出的,则需要知道输入字符串的编码才能正确显示它。 In the simplest case, the string is something like ASCII which maps one byte to one character. 在最简单的情况下,字符串类似于ASCII,将一个字节映射到一个字符。 So in a given input "414243", every two characters ("41", "42", "43) map to an ASCII value (65, 66, 67), which map to a character ("A", "B", "C"). 因此,在给定输入“414243”中,每两个字符(“41”,“42”,“43)映射到ASCII值(65,66,67),其映射到字符(”A“,”B“) , “C”)。

Here's how to that in 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"

Using std::strtol from <cstdlib> makes this easy; 使用<cstdlib> std::strtol可以轻松实现; if you insist on using a template class for this, use std::stringstream to perform the conversion of the single sub strings (like "41") to decimal values (65). 如果您坚持为此使用模板类,请使用std :: stringstream执行单个子字符串(如“41”)到十进制值(65)的转换。

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

沿着那条路线的东西?

Hex is a way of displaying binary data. Hex是一种显示二进制数据的方法。 It is not "raw data" as you say. 如你所说,它不是“原始数据”。 If the raw data you have contains a string, you should be able to see the string (possibly among other garbage) when you output it to the screen. 如果您拥有的原始数据包含一个字符串,那么当您将其输出到屏幕时,您应该能够看到该字符串(可能还有其他垃圾)。

Here's a loop to print the ASCII characters in a block of data. 这是一个在数据块中打印ASCII字符的循环。 To get anything else, you will have to deal with its format. 要获得其他任何东西,您将不得不处理其格式。

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;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM