myCSharp.de - DIE C# und .NET Community
Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

» Hauptmenü
myCSharp.de
» Startseite
» Forum
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Suche
   » Plugin für Firefox
   » Plugin für IE7
   » Gadget für Vista
» Regeln
» Wie poste ich richtig?
» Datenschutzerklärung
» wbb-FAQ

Mitglieder
» Liste / Suche
» Stadt / Anleitung dazu
» Wer ist wo online?

Angebote
» ASP.NET Webspace
» Bücher
» Zeitschriften
   » dot.net magazin
» Accessoires

Ressourcen
» .NET-Glossar
» guide to C#
» openbook: Visual C#
» openbook: OO
» .NET BlogBook
» MSDN Webcasts
» dotnetjob.de
» Search.Net

Team
» Kontakt
» Übersicht
» Wir über uns
» Bankverbindung
» Impressum

» Unsere MiniCity
MiniCity
» myCSharp.de Diskussionsforum
Du befindest Dich hier: Community-Index » Diskussionsforum » Gemeinschaft » .NET-Komponenten und C#-Snippets » Klasse für das Erstellen eines HexStrings aus Byte[] und auch wieder zurück.
Letzter Beitrag | Erster ungelesener Beitrag Druckvorschau | An Freund senden | Thema zu Favoriten hinzufügen

Antwort erstellen
Zum Ende der Seite springen  

Klasse für das Erstellen eines HexStrings aus Byte[] und auch wieder zurück.

 
Autor
Beitrag « Vorheriges Thema | Nächstes Thema »
TiltonJH TiltonJH ist männlich
myCSharp.de-Mitglied

images/avatars/avatar-3134.png


Dabei seit: 16.09.2006
Beiträge: 87
Entwicklungsumgebung: VS 2010 Pro
Herkunft: Leipzig


TiltonJH ist offline Füge TiltonJH Deiner Kontaktliste hinzu AIM Screenname von TiltonJH: TiltonJH YIM-Screenname von TiltonJH: TiltonJH MSN-Passport-Profil von TiltonJH anzeigen

Klasse für das Erstellen eines HexStrings aus Byte[] und auch wieder zurück.

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Beschreibung:

Auf der Suche nach Klassen und Methoden zum Wandeln von Byte[] in einen HexString und auch wieder zurück bin ich immer wieder auf halbfertige oder optimierungsbedürftige Snippets gestoßen.

Also dann doch selber machen. großes Grinsen

Hier nun meine Lösung.

Falls jmd noch Optimierungspotential findet, immer her damit. fröhlich

C#-Code:
using System;
using System.Text;

namespace Tools.Strings
{
    /// <summary>
    /// Provides methods for woking with hexadecimal values.
    /// </summary>
    public static class Hexadecimal
    {
        /// <summary>
        /// Determines if the <see cref="Char"/> is a hex digit.
        /// </summary>
        /// <param name="digit">A <see cref="Char"/>.</param>
        /// <returns><see langword="true"/>, if the given <see cref="Char"/> is a valid hex digit; - otherwise <see langword="false"/>.</returns>
        public static bool IsValidHexDigit(char digit)
        {
            return digit >= 0x30 && digit <= 0x39;
        }
        /// <summary>
        /// Determines if the <see cref="Char"/> is a lower case hex letter.
        /// </summary>
        /// <param name="letter">A <see cref="Char"/>.</param>
        /// <returns><see langword="true"/>, if the given <see cref="Char"/> is a lower case hex letter; - otherwise <see langword="false"/>.</returns>
        public static bool IsValidLowerCaseHexLetter(char letter)
        {
            return letter >= 0x61 && letter <= 0x66;
        }
        /// <summary>
        /// Determines if the <see cref="Char"/> is a upper case hex letter.
        /// </summary>
        /// <param name="letter">A <see cref="Char"/>.</param>
        /// <returns><see langword="true"/>, if the given <see cref="Char"/> is a upper case hex letter; - otherwise <see langword="false"/>.</returns>
        public static bool IsValidUpperCaseHexLetter(char letter)
        {
            return letter >= 0x41 && letter <= 0x46;
        }
        /// <summary>
        /// Determines if the <see cref="Char"/> is a valid hex char.
        /// </summary>
        /// <param name="hexChar">A <see cref="Char"/>.</param>
        /// <returns><see langword="true"/>, if the given <see cref="Char"/> is a valid hex char; - otherwise <see langword="false"/>.</returns>
        public static bool IsValidHexChar(char hexChar)
        {
            return Hexadecimal.IsValidHexDigit(hexChar) ||
                Hexadecimal.IsValidLowerCaseHexLetter(hexChar) ||
                Hexadecimal.IsValidUpperCaseHexLetter(hexChar);
        }
        /// <summary>
        /// Determines if the <see cref="String"/> is a valid hexString.
        /// </summary>
        /// <param name="hexString">A <see cref="String"/>.</param>
        /// <returns><see langword="true"/>, if the given <see cref="String"/> is a valid hexString; - otherwise <see langword="false"/>.</returns>
        public static bool IsValidHexString(string hexString)
        {
            if (hexString == null || hexString.Length == 0)
                return false;

            int i = 0;
            for (; i < hexString.Length; i++)
            {
                if (hexString[i] != ' ')
                    break;
            }
            if (i >= hexString.Length)
                return false;

            if (hexString.Length - i >= 2)
            {
                char one = hexString[i];
                char two = hexString[i + 1];
                if (one == '0' && (two == 'x' || two == 'X'))
                    i += 2;
            }

            if (i >= hexString.Length)
                return false;

            while (i < hexString.Length)
            {
                char c = hexString[i++];
                if (!(Hexadecimal.IsValidHexChar(c)))
                    return false;
            }

            return true;
        }
        /// <summary>
        /// Returns the <see cref="Byte"/> representation of an hexDigits.
        /// </summary>
        /// <param name="hexDigit">The hexDigit.</param>
        /// <returns>The <see cref="Byte"/> representation of an hexDigits.</returns>
        /// <exception cref="FormatException"><paramref name="hexDigit"/> is not a valid hexDigit.</exception>
        public static byte ToByte(char hexDigit)
        {
            if (Hexadecimal.IsValidHexDigit(hexDigit))
                return (byte)(hexDigit - 0x30);
            else if (Hexadecimal.IsValidLowerCaseHexLetter(hexDigit))
                return (byte)(hexDigit - 0x57);
            else if (Hexadecimal.IsValidUpperCaseHexLetter(hexDigit))
                return (byte)(hexDigit - 0x37);
            else
                throw new FormatException("Is not a valid hexDigit.");
        }
        /// <summary>
        /// Returns the <see cref="Byte"/> representation of two hexDigits.
        /// </summary>
        /// <param name="leftHexDigit">The left hexDigit.</param>
        /// <param name="rightHexDigit">The right hexDigit.</param>
        /// <returns>The <see cref="Byte"/> representation of two hexDigits.</returns>
        public static byte ToByte(char leftHexDigit, char rightHexDigit)
        {
            return (byte)(Hexadecimal.ToByte(leftHexDigit) << 4 | Hexadecimal.ToByte(rightHexDigit));
        }
        /// <summary>
        /// Converts a hexString into an array of <see cref="Byte"/>.
        /// </summary>
        /// <param name="hexString">A hexString to convert into an array of <see cref="Byte"/>.</param>
        /// <returns>An array of <see cref="Byte"/> representing the given <paramref name="hexString"/>.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="hexString"/> is <see langword="null"/>.</exception>
        /// <exception cref="FormatException"><paramref name="hexString"/> is not a valid hexString.</exception>
        public static byte[] ToBytes(string hexString)
        {
            if (hexString == null)
                throw new ArgumentNullException("hexString");
            if (hexString.Length == 0)
                return new byte[0];

            try
            {
                int i = 0;
                for (; i < hexString.Length; i++)
                {
                    if (hexString[i] != ' ')
                        break;
                }
                if (i >= hexString.Length)
                    return new byte[0];

                if (hexString.Length - i >= 2)
                {
                    char one = hexString[i];
                    char two = hexString[i + 1];
                    if (one == '0' && (two == 'x' || two == 'X'))
                        i += 2;
                }

                if (i >= hexString.Length)
                    return new byte[0];

                bool odd = (hexString.Length & 1) == 1;

                int length = hexString.Length - i >> 1;

                if (odd)
                    length++;

                byte[] bytes = new byte[length];
                int j = 0;

                if (odd)
                    bytes[j++] = ToByte(hexString[i++]);

                while (i < hexString.Length)
                {
                    bytes[j++] = ToByte(hexString[i++], hexString[i++]);
                }

                return bytes;
            }
            catch (Exception ex)
            {
                throw new FormatException("Is not a valid hex string.", ex);
            }
        }
        /// <summary>
        /// Returns a hex char.
        /// </summary>
        /// <param name="value">A <see cref="Int32"/> representing an hex char.</param>
        /// <returns>A <see cref="Char"/> representation of a given hex char.</returns>
        /// <exception cref="ArgumentOutOfRangeException"><paramref name="value"/> is not in range: 0 &lt;= value &lt;= 15</exception>
        public static char ToHexChar(int value)
        {
            if (value >= 0 && value <= 9)
                return (char)(value + 0x30);
            else if (value > 9 && value <= 15)
                //lower case 0x57
                //upper case 0x37
                return (char)(value + 0x57);
            else
                throw new ArgumentOutOfRangeException("value", value, "valid range: 0 <= value <= 15");
        }
        /// <summary>
        /// Converts an array of <see cref="Byte"/> into an hexString.
        /// </summary>
        /// <param name="bytes">An array of <see cref="Byte"/> to convert.</param>
        /// <returns>An <see cref="String"/> representation of the given array of <see cref="Byte"/>.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="bytes"/> is <see langword="null"/>.</exception>
        public static string ToString(byte[] bytes)
        {
            if (bytes == null)
                throw new ArgumentNullException("bytes");

            char[] chars = new char[bytes.Length << 1];
            for (int i = 0, bi = 0; i < chars.Length; )
            {
                byte b = bytes[bi++];
                chars[i++] = ToHexChar(b >> 4);
                chars[i++] = ToHexChar(b & 0xF);
            }
            return new string(chars);
        }
        /// <summary>
        /// Validates a <see cref="String"/> by removing all char which are not valid hex chars.
        /// </summary>
        /// <param name="hexString">A <see cref="String"/> to validate.</param>
        /// <returns>A validated <see cref="String"/>.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="hexString"/> is <see langword="null"/>.</exception>
        public static string ValidateHexString(string hexString)
        {
            if (hexString == null)
                throw new ArgumentNullException("hexString");
            if (hexString.Length == 0)
                return hexString;

            int i = 0;
            for (; i < hexString.Length; i++)
            {
                if (hexString[i] != ' ')
                    break;
            }
            if (i >= hexString.Length)
                return string.Empty;

            if (hexString.Length - i >= 2)
            {
                char one = hexString[i];
                char two = hexString[i + 1];
                if (one == '0' && (two == 'x' || two == 'X'))
                    i += 2;
            }

            if (i >= hexString.Length)
                return string.Empty;

            var sb = new StringBuilder(hexString.Length - i);
            while (i < hexString.Length)
            {
                char c = hexString[i++];
                if (Hexadecimal.IsValidHexChar(c))
                    sb.Append(c);
            }

            return sb.ToString();
        }
    }
}

EDIT: so was blödes, da waren noch ein paar käfer...
EDIT2: noch ne IsNullOrEmpty abfrage in IsValidHexString eingebaut
EDIT3: stark überarbeitet & kommentare eingefügt
EDIT4: weiter überarbeitet, leerzeichen am anfang werden nun übersprungen

Schlagwörter: <hexstring, hexadecimal, tostring, hexchar>

Dieser Beitrag wurde 9 mal editiert, zum letzten Mal von TiltonJH am 11.02.2010 16:50.

13.07.2009 17:35 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
JAck30lena JAck30lena ist männlich
myCSharp.de-Team (Admin)

images/avatars/avatar-2653.jpg


Dabei seit: 01.10.2006
Beiträge: 11.393
Entwicklungsumgebung: Visual Studio 05/08/10 Prof.


JAck30lena ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

C#-Code:
                    (c >= 0x41 && c <= 0x46) || // is lower case
                    (c >= 0x41 && c <= 0x46))   // is upper case

das solltest du ändern. es is beides das selbe... entgegen dem kommentar.
13.07.2009 17:40 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
TiltonJH TiltonJH ist männlich
myCSharp.de-Mitglied

images/avatars/avatar-3134.png


Dabei seit: 16.09.2006
Beiträge: 87
Entwicklungsumgebung: VS 2010 Pro
Herkunft: Leipzig

Themenstarter Thema begonnen von TiltonJH

TiltonJH ist offline Füge TiltonJH Deiner Kontaktliste hinzu AIM Screenname von TiltonJH: TiltonJH YIM-Screenname von TiltonJH: TiltonJH MSN-Passport-Profil von TiltonJH anzeigen

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Danke. Jup selber grad schon noch gersehn ;-)

MfG TiltonJH
13.07.2009 17:49 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Zwischen diesen beiden Beiträgen liegt mehr als ein Monat.
TiltonJH TiltonJH ist männlich
myCSharp.de-Mitglied

images/avatars/avatar-3134.png


Dabei seit: 16.09.2006
Beiträge: 87
Entwicklungsumgebung: VS 2010 Pro
Herkunft: Leipzig

Themenstarter Thema begonnen von TiltonJH

TiltonJH ist offline Füge TiltonJH Deiner Kontaktliste hinzu AIM Screenname von TiltonJH: TiltonJH YIM-Screenname von TiltonJH: TiltonJH MSN-Passport-Profil von TiltonJH anzeigen

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

hab mal neueren code rein gestellt. cool

-> stark überarbeitet & kommentare eingefügt

tilton
17.08.2009 18:40 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
McManta McManta ist männlich
myCSharp.de-Mitglied

Dabei seit: 31.08.2009
Beiträge: 3
Entwicklungsumgebung: Visual Studio 2005
Herkunft: Bodensee


McManta ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Das mit der Überprüfung des Strings auf Gültigkeit geht mit RegEx sehr einfach

C#-Code:
using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;

namespace McManta
{
    public static class HexStringConverter
    {
        public static bool IsHexString(string text)
        {
               return Regex.IsMatch(text, @"^[0-9A-Fa-f]+$");
        }
     }
}

Dann noch unötiges entfernen bzw. nötiges hinzufügen oder ein paar Exceptions werfen falls nötig

C#-Code:
public static byte[] String2Hex(string text)
{
           if (string.IsNullOrEmpty(text))
                throw new ArgumentNullException();

            // 0x entfernen
            if (text.StartsWith("0x"))
                text = text.Replace("0x","");

            // Leerzeichen entfernen z.B. 0a 0b 0c ff
            text = text.Replace(" ","");

            // 0 vorne hinzufügen, bei ungerader Anzahl von Zeichen
            if ((text.Length % 2) != 0)
                text = "0" + text;

            // Format prüfen
            if (!IsHexString(text))
                throw new FormatException();

            // konvertieren
            .........

          return byteResult;


}
31.08.2009 23:39 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
userid12529
myCSharp.de-Mitglied

Dabei seit: 07.07.2008
Beiträge: 208


userid12529 ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo McManta, hallo TiltonJH,

Ich würde bei der Validierung des HexStrings noch eine kleine Änderung vornehmen. Und zwar sollten die Leerzeichen im ersten Schritt entfernt werden und anschließend erst überprüft werden, ob der String mit "0x" beginnt. Ist zwar recht unwahrscheinlich, dass der String führende Leerstellen enthält, aber sicher ist sicher (eventuell könnte man es auch so erweitern, dass auch anderer Whitespace entfernt wird, bspw. Tabulatoren und Zeilenumbrüche).

Außerdem sollte die Überprüfung, ob der String mit "0x" anfängt, case insensitive realisiert werden:

C#-Code:
if (text.Substring(0, 2).ToLower().StartsWith("0x"))
    text = text.Substring(2);

Grüße,

Isaac
01.09.2009 09:32 Beiträge des Benutzers | zu Buddylist hinzufügen
TiltonJH TiltonJH ist männlich
myCSharp.de-Mitglied

images/avatars/avatar-3134.png


Dabei seit: 16.09.2006
Beiträge: 87
Entwicklungsumgebung: VS 2010 Pro
Herkunft: Leipzig

Themenstarter Thema begonnen von TiltonJH

TiltonJH ist offline Füge TiltonJH Deiner Kontaktliste hinzu AIM Screenname von TiltonJH: TiltonJH YIM-Screenname von TiltonJH: TiltonJH MSN-Passport-Profil von TiltonJH anzeigen

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo,

Zitat von McManta:
Das mit der Überprüfung des Strings auf Gültigkeit geht mit RegEx sehr einfach

Das mag sein, aber das Parsing und das Ausführen der RegEx braucht ne ganze Ecke mehr Rechenschritte als meine Implementierung.
D.h. RegEx ist einfach zu implementieren bzw. zu nutzen (bringt das Framework schon mit), aber aus Sicht der Performance ist es aufwendiger.

Zitat von McManta:
C#-Code:
...
text = text.Replace("0x","");
...

Ein Replace ist auch wieder aufwendiger als ein einfaches Überspringen der ersten 2 Zeichen. Ein Replace erzeugt einen neuen String (inkl. Speicherreservierung, Zeichen kopieren usw.). Von der Tasache das bei Replace der gesammte String mindestens einmal durchsucht werden muss, mal ganz abgesehn.

Zitat von McManta:
C#-Code:
...
if ((text.Length % 2) != 0)
...

Der Modulo wird intern mit Hilfe von Division errechnet (die genaue Formel hab ich grad nich im Kopf mal, wer 's wissen sollte mal Google/Wiki befragen ;-) ). Division ist eine sehr aufwendige Rechenoperation.
Ein simples Logisches & hingegen sehr sehr viel schneller.

Zitat von Isaac:
C#-Code:
if (text.Substring(0, 2).ToLower().StartsWith("0x"))
    text = text.Substring(2);

Alleine in "text.Substring(0, 2).ToLower()" werden 2 neue Strings erstellt.

Auf derlei Sachen wollte ich eben explizit verzichten.

Das Beachten/Filtern von Leerzeichen, ist jedoch eine Idee die ich mit einbauen könnte. Werde ich mir mal durch den Kopf gehen lassen.

Bei "StartsWith("0x")" kann ich mir vor stellen das es auch noch ein paar Optimierungen geben könnte, da werde ich mir mal anschaun, wie das dass Framework intern gelöst hat und ob was man besser machen könnte.

MfG

TiltonJH
01.09.2009 18:58 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Floste
myCSharp.de-Mitglied

images/avatars/avatar-2376.jpg


Dabei seit: 13.06.2007
Beiträge: 1.131
Entwicklungsumgebung: VS 2008
Herkunft: Norddeutschland


Floste ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Mit meinem  Zahlensystem Converter gehts auch, sofern man das richtige Alphabet angibt: new char[16]{'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};

Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Floste am 01.09.2009 19:25.

01.09.2009 19:25 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Zwischen diesen beiden Beiträgen liegen mehr als 4 Monate.
markus111 markus111 ist männlich
myCSharp.de-Mitglied

images/avatars/avatar-3108.png


Dabei seit: 01.10.2008
Beiträge: 479
Entwicklungsumgebung: Visual Studio 2010 Pro
Herkunft: Henstedt-Ulzburg


markus111 ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo,

schaut ja gut aus fröhlich nur - diese Funktion besitzt das .NET Framework doch schon, mit der Convert Klasse? (Convert.ToString(0xAB, 16) und int.Parse("0x12", NumberStyles.HexNumber)).

mfg.
markus111

Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von markus111 am 22.01.2010 14:35.

22.01.2010 14:35 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
TiltonJH TiltonJH ist männlich
myCSharp.de-Mitglied

images/avatars/avatar-3134.png


Dabei seit: 16.09.2006
Beiträge: 87
Entwicklungsumgebung: VS 2010 Pro
Herkunft: Leipzig

Themenstarter Thema begonnen von TiltonJH

TiltonJH ist offline Füge TiltonJH Deiner Kontaktliste hinzu AIM Screenname von TiltonJH: TiltonJH YIM-Screenname von TiltonJH: TiltonJH MSN-Passport-Profil von TiltonJH anzeigen

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo,

ja eine ähnliche Funktion besitzt das .Net Framework schon. Aber eben nur ähnlich.

Einen Int32 oder Int64 in hex wandeln und wieder zurück nützt ja nur für 1 bis 8 Byte lange HexStrings etwas. Und selbst dann ist das Ergebnis eben ein int und kein Byte[].

Es gibt keine Funktion mit der man von einen beliebig langen HexString in Byte[] wandeln kann. Auch gibt es keine mir bekannte Möglichkeit ein beliebig großes Byte[] in HexString wandeln könnte. Deswegen also hier diese Klasse.

MfG

TiltonJH
24.01.2010 16:35 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
TiltonJH TiltonJH ist männlich
myCSharp.de-Mitglied

images/avatars/avatar-3134.png


Dabei seit: 16.09.2006
Beiträge: 87
Entwicklungsumgebung: VS 2010 Pro
Herkunft: Leipzig

Themenstarter Thema begonnen von TiltonJH

TiltonJH ist offline Füge TiltonJH Deiner Kontaktliste hinzu AIM Screenname von TiltonJH: TiltonJH YIM-Screenname von TiltonJH: TiltonJH MSN-Passport-Profil von TiltonJH anzeigen

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo,

ich habe oben eine nochmal überarbeitete Version rein gestellt. Leerzeichen am Anfang werden nun übersprungen, auch die String.StartsWith() habe ich durch performanteren Code ersetzt.

Strings, wie beispielsweise: "0x01 23 45 67 89 ab cd ef AB CD EF", werden aber immer noch nicht übersetzt. Hier hilft ein:

C#-Code:
Hexadecimal.ToBytes (Hexadecimal.ValidateHexString ("0x01  23  45  67  89  ab  cd  ef  AB  CD  EF"))

aber stark weiter cool .

MfG

Tilton
11.02.2010 16:57 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Baumstruktur | Brettstruktur       | Top 
myCSharp.de | Forum Der Startbeitrag ist älter als 3 Jahre.
Der letzte Beitrag ist älter als 3 Jahre.
Antwort erstellen


© Copyright 2003-2013 myCSharp.de-Team. Alle Rechte vorbehalten. 23.05.2013 23:54