Entwickler-Ecke

Basistechnologien - Aus HexString eine bestimmte Stelle ausschneiden


epsodus - Fr 09.10.15 15:02
Titel: Aus HexString eine bestimmte Stelle ausschneiden
Hallo,
ich habe folgendes Problem. In einer textBox steht ein HexString z.B.

010100DF00012020373733343837012030303030303030006501 4B323633333939 01000000000000000000040232303134303

ich möchte den Teil zwischen 6501 und 0100 auschneiden und in einer ander textBox ausgeben.
Wie kann ich diesen teil ausschneiden ? mit Trim oder regex ? Komme hier nicht weiter.

MfG. Epsodus


Moderiert von user profile iconTh69: Topic aus WinForms verschoben am Fr 09.10.2015 um 15:48


Th69 - Fr 09.10.15 15:47

Hallo,

ausschneiden kannst du einfach mittels der String.Substring-Methode [https://msdn.microsoft.com/de-de/library/aka44szs%28v=vs.110%29.aspx]. Du mußt nur die Indizes bestimmen, z.B. mittels einer der String.IndexOf-Methoden [https://msdn.microsoft.com/de-de/library/system.string.indexof%28v=vs.110%29.aspx].


Greenberet - Fr 09.10.15 17:23

Meiner Meinung nach würde sich hier String.Split [https://msdn.microsoft.com/de-de/library/b873y76a%28v=vs.110%29.aspx] am besten eignen.

du bekommst in diesem Fall dann einen Array von 3 Strings zurück
[0] = "010100DF00012020373733343837012030303030303030006501"
[1] = "4B323633333939"
[2] = "01000000000000000000040232303134303"


Th69 - Fr 09.10.15 18:54

Aber nur, wenn auch wirklich dort ein Leerzeichen ist (und nicht, wie ich vermute, nur hier im Forum so gepostet wurde, daß man es besser erkennt).


epsodus - Fr 09.10.15 19:32

Hallo,

zur Verdeutlichung, ich habe die Ausgabe der textBox geändert

boxHex.Text = FormatString(hexString, " ", 0x2);

01 01 00 DF 00 01 20 20 37 37 33 34 38 37 01 20 30 30 30 30 30 30 30 00 65 01 4B 32 36 33 33 39 39 01 00 00 00

Die gesuchte Stelle habe ich extra ausgerückt.

Der String von 01 01...65 01 kann verschieden lang sein, als Idenifizierung ist hier 65 01


Ralf Jansen - Fr 09.10.15 19:49

Dann gilt weiter der Hinweis von TH69.
Du mußt dir nur überlegen ob du das auf den Inhalt von boxHex.Text willst oder auf hexString das können wir ohne weiteren Infos nicht entscheiden.
Eigentlich fehlen da eh noch zusätzliche Infos. Können die beiden Marker Hexwerte 6501 und 0100 nicht mehrmals vorkommen und was dann?


epsodus - Fr 09.10.15 20:11

Das kann auch auf den HexString gehen, die textbox ist nur rein informativ.
Der Marker 6501 und 0100 kommt einmalig vor, deshalb soll an den Stellen der cut erfolgen.


hRb - Fr 09.10.15 23:51

Hallo,
wenn Die Hex-Daten in einem Textfeld stehen, dann versuch es doch mit PosEx. Hier ein Beispiel.
Vorgabe ein Richedit gefüllt mit Hex-Daten, ein Label und ein Button. Es liefert Dir das Ergebnis.
Gruß hRb


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
procedure TForm1.Button1Click(Sender: TObject);
type
 tparam =record
    text:string;
    end;
var n1,n2,c:integer;
    sb1,sb2,s:string;
    bosHex:tparam;
begin
  bosHex.text:=Richedit1.text;
  if bosHex.Text[3]=' '
    then begin sb1:='65 01'; sb2:='01 00'; c:=5;end
    else begin sb1:='6501';  sb2:='0100'; c:=4 end;
   n1:=PosEx(sb1, bosHex.Text,1);
  if n1=0 then exit; //Fehler
  n2:=PosEx(sb2, bosHex.Text,n1);
  if n2=0 then exit; //Fehler
  s:=copy(bosHex.Text,n1+c,n2-n1-c);
  label1.caption:=s;
end;


epsodus - So 11.10.15 08:25

Ersteinmal Danke an alle,

also soweit bin ich :

ich schaffe es so abzubilden

C#-Quelltext
1:
string[] splittetString = hexString.Split(new[] { "6501" }, StringSplitOptions.None);                    

4B32363333393901000000000000000000040232303134303531353131

Den vorderen Teil bekomme ich abgeschnitten, aber wie kann ich den hinteren Teil noch abscheiden, so das nur

4B323633333939 stehen bleibt ?

Moderiert von user profile iconTh69: C#-Tags hinzugefügt


Ralf Jansen - So 11.10.15 12:44

Der Vorschlag war IndexOf und SubString zu verwenden.


C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
class Program
{
    static void Main(string[] args)
    {
        string hex = "010100DF000120203737333438370120303030303030300065014B32363333393901000000000000000000040232303134303";

        Console.WriteLine(hex.MySubString("6501""0100"));
    }
}

public static class StringExtensions
{
    public static string MySubString(this string hex, string start, string end)
    {
        int startIndex = hex.IndexOf(start);
        if (startIndex < 0)
            return string.Empty;
        startIndex += start.Length;

        int endIndex = hex.IndexOf(end, startIndex);
        if (endIndex < 0)
            return string.Empty;

        return hex.Substring(startIndex, endIndex - startIndex);
    }
}


epsodus - Di 13.10.15 10:47

Hallo,

ich möchte Danke sagen, es funktioniert. Meine Ausgabe habe ich wie folgt umgesetzt:

C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
// VIN HEX ausgeschnitten
string hex = boxHex.Text;
BoxTest.Text = (hex.MySubString("6501""0100"));

// Vin HEX to ASCII
HexConverter HexConvert = new HexConverter();
string sData = BoxTest.Text;
boxAsci.Text = HexConvert.HexadecimalToString(sData);


Moderiert von user profile iconTh69: C#-Tags hinzugefügt


epsodus - So 18.10.15 18:06

Hallo,

da habe ich den Mund wohl zu voll genommen.
Es gibt nicht nur den Suchbereich 6501, 0100 sondern auch 5901, 0100 und 3701, 0100.

Also

C#-Quelltext
1:
2:
3:
(hex.MySubString("3701""0100"))
(hex.MySubString("5901""0100"))
(hex.MySubString("6501""0100"))

meine Ausgabe sieht wie folgt aus:

C#-Quelltext
1:
2:
3:
// VIN HEX ausgeschnitten
string hex = boxHex.Text;
BoxTest.Text = (hex.MySubString("6501""0100"));

wie kann ich denn jetzt die richtige Auisgabe anzeigen lassen? Mit einer Schleife?

Moderiert von user profile iconTh69: C#-Tags hinzugefügt


Ralf Jansen - So 18.10.15 21:10

Zitat:
wie kann ich denn jetzt die richtige Auisgabe anzeigen lassen ? Mit einer Schleife ?


Was ist denn dir richtige Ausgabe? Wir/Du brauchen schon eine klare Definition deiner Erwartung.

Sind alle Suchbereiche zusammen das Ergebnis oder einer daraus? Wenn einer, was ist wenn mehrere gefunden werden? Gibt es da eine Reihenfolge?
Du musst schon genauer definieren was die Ausgabe sein soll.


epsodus - Mo 19.10.15 06:22

Hallo,

es gibt tatsächlich mehrere Suchbereiche, also drei Stück. Pro File (Datei) kann nur einer vorkommen.

Es kann pro File ( Datei ) nur einer von diesen drei sein :
Es wird auch immer nur ein File (Datei) geladen.

C#-Quelltext
1:
2:
3:
(hex.MySubString("3701""0100"))
(hex.MySubString("5901""0100"))
(hex.MySubString("6501""0100"))


Von aussen ist nicht zu sehen welches Kriterium zum tragen kommt.
Wenn ich die Datei auswähle, wollte ich im Vorfeld prüfen welcher SubString vorhanden ist
und danach den erforderlichen SubString auswählen.
So das der richtige zum ausschneiden ausgewählt wird.

Habe mit einem Hexeditor mal alle Dateien durchgeschaut, es sind nur diese drei möglich.

Moderiert von user profile iconTh69: C#-Tags hinzugefügt

Entschuldigung , ich achte nächstesmal auf die C#-Tags.


epsodus - Mi 21.10.15 08:20

Hallo ich versuche es mal chronologisch zu beschreiben :

Ich lese zuerst ein File ein, mit :


C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
 private void selectFile_Click(object sender, EventArgs e)
        {
            OpenFileDialog browser = new OpenFileDialog
            {
                InitialDirectory = Application.StartupPath + "FSCBMW/",    // Der Ordner, in dem sich die Anwendung befindet
                Filter = "FSC files (*.FSC)|*.FSC",
                // Filter = "txt files (*.txt)|*.txt|All files (*.*)|*.*", 
                FilterIndex = 2,
                RestoreDirectory = true,
                CheckFileExists = true
            };


Das File wird in einer Textbox angezeigt und liegt in HEX vor


C#-Quelltext
1:
boxHex.Text = FormatString(hexString, ""2);                    


Dazu gibt es 3 Files die vorkommen können, es wird aber immer nur eines geladen bzw. eingelesen.



C#-Quelltext
1:
2:
3:
4:
5:
010100190001393938382020303002202020202020202032333333 3701 43523133303535 0100 0000

010100DF0001202037373334383701203030303030303000 6501 4B323633333939 0100 0000

0101001B0001202037373334383701203238373338363302 5901 45333937363430 0100 000


Die Leerzeichen habe ich absichtlich eingefügt , der Übersichthalber.

Das Identifikationsmerkmal ist 3701 0100 oder 6501 0100 oder 5901 0100

Die Zeichen dazwischen möchte ich ausschneiden. Dazu hat mir Rolf Jansen geholfen


C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
    public static class StringExtensions
    {
        public static string MySubString(this string hex, string start, string end)
        {
            int startIndex = hex.IndexOf(start);
            if (startIndex < 0)
                return string.Empty;
            startIndex += start.Length;

            int endIndex = hex.IndexOf(end, startIndex);
            if (endIndex < 0)
                return string.Empty;

            return hex.Substring(startIndex, endIndex - startIndex);
        }
    }
}


Im Vorfeld ging ich immer von nur einem Merkmal aus, welches ich wie folgt auswerte :


C#-Quelltext
1:
2:
3:
 // VIN HEX ausgeschnitten
            string hex = boxHex.Text;
            BoxTest.Text = (hex.MySubString("6501""0100"));


Wie kann ich eine Identifikation vornehmen, welches Merkmal in der Textbox


C#-Quelltext
1:
boxHex.Text = FormatString(hexString, ""2);                    

vorliegt. So das der richtige hex.Substring benutzt wird ?



C#-Quelltext
1:
2:
3:
(hex.MySubString("3701""0100"));
(hex.MySubString("5901""0100"));
(hex.MySubString("6501""0100"));


Ralf Jansen - Mi 21.10.15 10:29

Ich würde einfach nach denn Möglichkeiten Suchen und dann einen davon verwenden. z.B.
Ich denke aber das das letztlich so nicht 100% funktionieren kann. Warum sollten die 3 Werte nicht auch an anderer Stelle vorhanden sein also zum Beispiel in dem Teil den du da ausschneidest?


C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
class Program
{
    static void Main(string[] args)
    {            
        string hex = "0101001B00012020373733343837012032383733383633025901453339373634300100000";

        string start = hex.MyFindFirst("6501""5901""3701");

        if(!string.IsNullOrEmpty(start))  // es gibt einen Marker
            Console.WriteLine(hex.MySubString(start, "0100"));
        else
            Console.WriteLine("Marker not found.");
    }
}

public static class StringExtensions
{
    public static string MySubString(this string hex, string start, string end)
    {
        int startIndex = hex.IndexOf(start);
        if (startIndex < 0)
            return string.Empty;
        startIndex += start.Length;

        int endIndex = hex.IndexOf(end, startIndex);
        if (endIndex < 0)
            return string.Empty;

        return hex.Substring(startIndex, endIndex - startIndex);
    }

    public static string MyFindFirst(this string hex, params string[] values)
    {
        foreach (var value in values)
        {
            int index = hex.IndexOf(value);
            if (index > 0)
                return value;
        }
        return string.Empty;
    }
}


epsodus - Mi 21.10.15 11:36

Hallo Ralf, wenn ich Dich beim Vornamen nennen darf.

Die Werte sind immer vor und nach dem Inhalt, den ich suche.

Es fängt immer mit 3701 oder 5901 oder 6501 an und hört mit 0100 auf.

Ich teste es mal, ich habe auch mit einer If Schleife gearbeitet, aber zu kompliziert gedacht.


epsodus - Mi 21.10.15 11:59

Hallo Ralf,

es funktioniert prächtig, meine Abfrage ist jetzt wie folgt :


C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
            // VIN HEX ausgeschnitten
        string hex = boxHex.Text;

        string start = hex.MyFindFirst("6501""5901""3701");

        if(!string.IsNullOrEmpty(start))  // es gibt einen Marker
            BoxTest.Text =(hex.MySubString(start, "0100"));
        else
            MessageBox.Show("Marker not found.");


Sage Danke, jetzt habe ich was dazu gelernt.