Sie betrachten eine ältere Version der ionflux.org website! Bitte besuchen Sie die neue Version
hier.
Hexadezimale Ausgabe (C++)
Es kommt öfter vor, dass ich einen Blick auf Daten werden möchte, die von
Quellcode erzeugt werden, den ich geschrieben habe, obwohl diese Daten für
Menschen nicht sehr gut verständlich sind. Im schlimmsten Fall können sie
sogar Zeichen enthalten, die gar nicht dargestellt werden können. Für diese
Situationen habe ich einige kleine Funktionen geschrieben, die beliebige
Byte-Daten in hexadezimaler Notation ausgeben, ganz ähnlich wie bei einem
Hexadezimal-Editor. Es ist auch möglich, die hexadezimale Repräsentation neben
den lesbaren Zeichen darzustellen.
Konverter von Bytes zu Hexadezimal-Zeichenkette
Dieser Schnipsel erfüllt die einfache Funktion, eine Kette von Bytes in eine
Zeichenkette von hexadezimalen Ziffern umzuwandeln.
#include <string>
#include <sstream>
#include <iomanip>
std::string make_hex(const std::string& inputData)
{
std::ostringstream buffer;
buffer << std::uppercase << std::right << std::setfill('0') << std::hex;
for (unsigned int i = 0; i < inputData.size(); i++)
buffer << std::setw(2) << int(static_cast<unsigned char>(inputData[i]));
return buffer.str();
}
Lesbaren Text erstellen
Einige Zeichen können als lesbar betrachtet werden, selbst in einer Suppe von
zufälligen Bytes. Dieses Stück Code ersetzt Zeichen, die nicht als lesbar
betrachtet werden, mit einem Ersatzzeichen. Alle anderen Zeichen werden
unverändert übernommen. Falls UTF-8 Kodierung verfügbar ist (siehe die
Codeschnipsel im vorangegangenen Abschnitt), kann die Version weiter unten
benutzt werden, um wesentlich mehr Zeichen anzuzeigen. Die mögen zwar nicht
alle lesbar sein, aber sie sehen auf jeden Fall interessant aus. ;-)
#include <string>
#include <sstream>
std::string make_readable(const std::string& inputData,
const std::string& replacement = ".")
{
std::ostringstream buffer;
unsigned char currentChar;
for (unsigned int i = 0; i < inputData.size(); i++)
{
currentChar = static_cast<unsigned char>(inputData[i]);
if (((currentChar >= 32) && (currentChar <= 126))
|| (currentChar >= 160))
buffer << inputData[i];
else
buffer << replacement;
}
return buffer.str();
}
/* Dies erfordert die uint_to_utf8() Funktion aus dem vorangegangenen
Abschnitt. */
std::string make_readable(const std::string& inputData,
const std::string& replacement = ".")
{
std::ostringstream buffer;
unsigned int currentChar;
for (unsigned int i = 0; i < inputData.size(); i++)
{
currentChar = static_cast<unsigned int>(
static_cast<unsigned char>(inputData[i]));
if ((currentChar >= 32) && (currentChar <= 126))
buffer << inputData[i];
else
if (currentChar >= 127)
buffer << uint_to_utf8(currentChar);
else
buffer << replacement;
}
return buffer.str();
}
Nett aussehende Hexadezimal-Ausgabe erzeugen
Nun sind wir in der Lage, wirklich nette Dinge mit der hexadezimalen
Zeichenkette und der lesbaren Repräsentation der Daten anzustellen. Die
folgende Funktion erzeugt ein Spalten-Layout, das die Bytes neben den lesbaren
Zeichen anzeigt. Die Version ganz unten setzt einige Standardwerte ein und
führt alles zu einer Hex-Ausgabe zusammen, die wirklich einfach zu benutzen
ist, wenn Daten einer genaueren Untersuchung bedürfen.
#include <string>
#include <sstream>
std::string make_nice_hex(const std::string& hex, const std::string& readable,
int bytesPerLine, int groupBytes)
{
std::ostringstream buffer;
std::string paddedHex(hex);
std::string paddedReadable(readable);
if ((paddedHex.size() % 2) != 0)
paddedHex.append(" ");
while (((paddedHex.size() / 2) % bytesPerLine) != 0)
paddedHex.append(" ");
unsigned int bytes = paddedHex.size() / 2;
while (paddedReadable.size() < bytes)
paddedReadable.append(" ");
int readablePos = 0;
for (unsigned int i = 0; i < bytes; i++)
{
buffer << paddedHex.substr(2 * i, 2) << " ";
if ((((i + 1) % groupBytes) == 0) && (((i + 1) % bytesPerLine) != 0))
buffer << " ";
if (((i + 1) % bytesPerLine) == 0)
{
buffer << " " << paddedReadable.substr(readablePos, bytesPerLine) << "n";
readablePos += bytesPerLine;
}
}
return buffer.str();
}
std::string make_nice_hex(const std::string& data, int bytesPerLine = 20,
int groupBytes = 10)
{
return make_nice_hex(make_hex(data), make_readable(data, "."),
bytesPerLine, groupBytes);
}