Mittwoch, 29. Oktober 2008

Hexadezimaldarstellung eines Strings nach Int32 umrechnen - bbo-Style

Wie tropensturm Hex-Strings nach Int32 konvertiert, haben wir heute schon gelernt. Natürlich hat er gleich wieder Forderungen gestellt, also kommt hier meine Version.

Zunächst muss ich anmerken, dass ich wesentlich pragmatischer an die Sache herangegangen bin. Ich habe Dinge wie Encoding und Little- / Big-Endian vernachlässigt, denn ich brauchte schnell eine funktionierende Lösung für einen Test.

Folgender Code ist bei mir dabei heraus gekommen:

   1:  public static int ConvertHexStringToInt(string hexString)         
   2:  {
   3:      string hex = "0x";
   4:   
   5:      for (int i = 0; i < hexString.Length; i++)
   6:      {
   7:          hex += ((int)hexString[i]).ToString("X");
   8:      }
   9:   
  10:      return Convert.ToInt32(hex, 16);
  11:  }

Im Prinzip ist das, was ich hier tue, eigentlich recht einfach.
Zunächst lege ich mir eine String-Variable an, die die hexadezimale Darstellung des übergebenen Strings aufnehmen soll. In der for-Schleife sorge ich entsprechend dafür, dass dies auch so ist. In Zeile 7 wandle ich zunächst jeden Buchstaben des Übergabe-Strings in seine ASCII-Int32-Repräsentation, die anschließend nach Hexadezimal konvertiert und dem finalen String angehängt wird.
Ist die Schleife für alle Zeichen des Strings durchlaufen worden, haben wir einen String im Format 0xA9AE.
Diesen String konvertiere ich dann in Zeile 10 noch nach Int32, wobei ich eine Basis von 16 (also hexadezimal) angebe und gebe das Ergebnis zurück.

So weit, so einfach...
... leider aber auch so "beschränkt".
Durch das Konvertieren jedes Buchstabens in seine Int32-Repräsentation in Zeile 7 wird diese Lösung auf Zeichen beschränkt, die im ASCII-Zeichensatz vorhanden sind. Werden Zeichen verwendet, die in diesem nicht auftauchen, führt das zu falschen Ergebnissen.

FAZIT:
Für meine Zwecke ist diese Implementierung absolut ausreichend, da ich mir sicher sein kann, dass mein Übergabe-String nur Zeichen enthält, die auch im ASCII-Zeichensatz auftauchen. Für einen produktiven Einsatz ist aber auf jeden Fall tropensturms Lösung vorzuziehen, da diese eben auch mit nicht ASCII-konformen Zeichen umgehen kann.

bbo-Style: 0
tropensturm-Style: 1

2 Kommentare:

Anonym hat gesagt…

Hi,

wie kommst du darauf das in Zeile 7 es nur auf ASCII beschränkt wird? In .Net ist ein Char ein Unicode-Char. Ein zugriff per Index auf einen string liefert einen UniCode-Char. Heißt: Deine Lösung sollte auch in Ordnung sein.

Grüße,
Jens

Tropensturm hat gesagt…

Hi Jens,

es ist korrekt das char unter .net als 2 byte Unicode kodiert ist und in dieser Hinsicht rechnet seine Funktion auch vollkommen richtig. Jedoch war seine Aufgabenstellung ein Zeichen in eine 1 Byte Repräsentation umzurechnen.

Sein Problem ist, das Unicode eine Übermenge von ASCII ist. Bis Position 0x007F (also die ersten 127 Zeichen) ist der Hexwert eines Unicodewertes identisch mit denen aus ASCII: http://www.utf8-zeichentabelle.de/

Darüber hinaus, jedoch findet dann eine vollständige 2 Byte Kodierung statt. Zeichen 128 ist dann bereits schon mit 0xC280 kodiert. Er kann es also ohne weitere Formatkonvertierung nicht mehr auf ein Byte pro Zeichen kommen, daher rechnet seine Funktion ab dem 128. Zeichen in der Unicode Tabelle vollständige 2 Byte Unicodes, während sie bis 127 ASCII kompatible 1 Byte Werte berechnete.

Grüße,
Mark