vb@rchiv
VB Classic
VB.NET
ADO.NET
VBA
C#
Top-Preis! AP-Access-Tools-CD Volume 1  
 vb@rchiv Quick-Search: Suche startenErweiterte Suche starten   Impressum  | Datenschutz  | vb@rchiv CD Vol.6  | Shop Copyright ©2000-2024
 
zurück

 Sie sind aktuell nicht angemeldet.Funktionen: Einloggen  |  Neu registrieren  |  Suchen

VB.NET - Fortgeschrittene
Hexwert in String Halbbyte für Halbbyte umwandeln 
Autor: Schudi
Datum: 20.11.18 17:03

Ergänzend zu meinem vorherigen Post noch einmal ein losgelöstes Thema:

Ich habe eine Stringvariable, die den Hexadezimalen Wert "01 15" enthält.

Diese "steht" für den "realen" Wert "115" (hex: 31 31 35) - also eine Ziffer je Halbbyte.

Das nennt sich "gepacktes Datenformat" oder in COBOL (ja, gab es mal ...) Comp-6.

Wie kann ich den Hexwert Halbbyte für Halbbyte auslesen und wieder in den String zurück "verwandeln".

Vielen Dank für möglichen Hilfen und "sorry" falls dies einen Doppelpost darstellen sollte. Es ging mir darum, ein Teilproblem heraus zu lösen, um so evtl. besser zu einem Lösungsansatz zu gelangen.
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Hexwert in String Halbbyte für Halbbyte umwandeln 
Autor: Manfred X
Datum: 20.11.18 17:44

Hallo !

Da ich mich mit COBOL-Typen nicht auskenne
und Deine Angaben zu String-Konvertierung und
zur Byte-Packung nicht so ganz eindeutig sind,
kann ich im Moment nur zu einer Analyse/Konvertierung
des Dateiinhalts auf Bitebene raten.

  Using fs As New IO.FileStream("G:\daten\.....", IO.FileMode.Open, _
    IO.FileAccess.Read)
     Dim bytes(CInt(fs.Length - 1)) As Byte
     fs.Read(bytes, 0, bytes.Length)
     Dim bm As New BitArray(bytes)
     '.... ab hier ist eine indizierter Zugriff (nullbasiert)
     'auf die einzelnen Bits möglich
     'Damit kanst Du die exakte Position und Länge Deiner
     'einzelnen Datenfelder ermitteln und Bit-Folgen zu Daten-Werten 
     'konvertieren.
  End Using
Beispiele zur Nutzung des Bitkonverters findest Du hier:
https://www.vbarchiv.net/tipps/details.php?id=1987

Beitrag wurde zuletzt am 20.11.18 um 17:48:09 editiert.
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Hexwert in String Halbbyte für Halbbyte umwandeln 
Autor: eierlein
Datum: 21.11.18 19:44

Sub test()
        Dim t1 As String = Chr(&H1) & Chr(&H15)
        Dim e As String, i As Int16
 
        e = Convert.ToInt16(GetChar(t1, 1)).ToString("X") & Convert.ToInt16( _
          GetChar(t1, 2)).ToString("X2")
        i = Convert.ToInt16(e)  ' nur,wenn du mit der Zahl rechnen willst
 
        Debug.Print(e)
        Debug.Print(i)
 
    End Sub
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Hexwert in String Halbbyte für Halbbyte umwandeln (COBOL Comp-6-Format) 
Autor: Schudi
Datum: 26.11.18 14:36

Hallo und vielen Dank eierlein,

Deine Routine klappt wunderbar - bis auf eine Kleinigkeit:

0er wurden teilweise unterdrückt...

Aus hex"20150423" wurde "2015423" statt "20150423". Die 0 aus "04" wurde also unterdrückt.

Ich habe Deinen Code daher minimal angepasst und immer "X2" statt "X" und "X2" verwendet:

Function test16(t1 As String) As Short
 
        Dim e As String, i As Int16
 
        e = Convert.ToInt16(GetChar(t1, 1)).ToString("X2") & Convert.ToInt16( _
          GetChar(t1, 2)).ToString("X2")
        i = Convert.ToInt16(e)  ' nur,wenn du mit der Zahl rechnen willst
 
        Return i
 
End Function
Mit dem Format-String "X2" klappt es perfekt und es kommt das gewünschte Ergebnis raus: 115

Um den Code nun nicht für 2-Byte und 4-Byte Werte verdoppeln zu müssen, bin ich zu folgender Verallgemeinerung gekommen:

    Function Test(t1 As String) As Integer
 
        Dim e As String = ""
 
        For i = 1 To Len(t1)
            e = e & Convert.ToInt16(GetChar(t1, i)).ToString("X2")
        Next
 
        Return Convert.ToInt32(e)
 
    End Function
Damit kommt sowohl die "115" als auch die "20150423" korrekt und vollständig raus.

Nochmals vielen Dank an alle die mir geantwortet haben für die schnelle und kompetente Hilfe!!!

Ich habe wieder was dazu gelernt.
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Hexwert in String Halbbyte für Halbbyte umwandeln (COBOL Comp-6-Format) 
Autor: Schudi
Datum: 26.11.18 15:24

zu früh gefreut...

   Function Test(t1 As Char()) As Integer
 
        Dim e As String = ""
 
        For i = 1 To Len(t1)
            e = e & Convert.ToInt32(GetChar(t1, i)).ToString("X2")
        Next
 
        Return Convert.ToInt32(e)
 
    End Function
Mit hex"20150423" klappt es. Mit"20150117" und "20170703" auch, aber mit hex"19991018" nicht...

Aus der "99" wird "FFD" - insgesamt also "19FFD1018" statt "19991018"


Wenn ich die Datei mit Encoding.AScii einlese kommt "193F1018" raus...

Beitrag wurde zuletzt am 26.11.18 um 15:37:19 editiert.
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Hexwert in String Halbbyte für Halbbyte umwandeln (COBOL Comp-6-Format) 
Autor: eierlein
Datum: 26.11.18 15:44

Nimm ChrW statt Chr.

Dann klappt's auch mit Werten > 127 (7F hex)
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Hexwert in String Halbbyte für Halbbyte umwandeln (COBOL Comp-6-Format) 
Autor: Schudi
Datum: 26.11.18 16:24

zu früh gefreut...

   Function Test(t1 As Char()) As Integer
 
        Dim e As String = ""
 
        For i = 1 To Len(t1)
            e = e & Convert.ToInt32(GetChar(t1, i)).ToString("X2")
        Next
 
        Return Convert.ToInt32(e)
 
    End Function
Mit hex"20150423" klappt es. Mit"20150117" und "20170703" auch, aber mit hex"19991018" nicht...

Aus der "99" wird "FFD" - insgesamt also "19FFD1018" statt "19991018"

Das Programm, mit dem die Datei erzeugt wurde, stammt noch aus MS-Dos-Zeiten, kennt also nur den ASCII-Zeichensatz. Wenn ich die Datei mit Encoding.AScii einlese kommt "193F1018" raus...

Als t1 wird folgendes übergeben bzw. aus der Datei mit ReadChars(4) gelesen:

In der Datei steht lt. Hex-Editor: "19 99 10 18"

Encoding.Ascii

Chrw(25) & "?" & Chrw(16) & Chrw(24)

Dez 25 = hex"19" passt
Dez 63 = hex "3F" pass nicht
Dez 16 = hex "10" passt
Dez(24) = hex "18" passt

Encoding.Default

Chrw(25) & "TM" & Chrw(16) & Chrw(24)

Dez 25 = hex"19" passt
Dez ?? = hex "2122" pass nicht
Dez 16 = hex "10" passt
Dez(24) = hex "18" passt


Ohne Encoding-Angabe

Chrw(25) & "�" & Chrw(16) & Chrw(24)

Dez 25 = hex"19" passt
Dez ?? = hex "FFD" pass nicht
Dez 16 = hex "10" passt
Dez(24) = hex "18" passt

Mit Encoding.GetEncoding(850) sieht es noch am Besten aus:

Chrw(25) & "Ö" & Chrw(16) & Chrw(24)

Dez 25 = hex"19" passt
Dez 153 = hex "99" pass (bzw. würde passen) aber das "Ö" wird zu "D6" konvertiert...
Dez 16 = hex "10" passt
Dez(24) = hex "18" passt

Das "Ö" wird also zu "D6" - wobei "Ö" in der Ascii-Tabelle tatsächlich schon hex"99" ist...

Ich steh auf dem sprichwörtlichen Schlauch...
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Hexwert in String Halbbyte für Halbbyte umwandeln (COBOL Comp-6-Format) 
Autor: Schudi
Datum: 26.11.18 16:34

Entschuldige, aber wie meinst Du das?

GetChrW statt GetChr? Da kommt eine Meldung, dass es diese Funktion nicht gibt...

Sorry wenn ich zu blöd bin...
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Hexwert in String Halbbyte für Halbbyte umwandeln (COBOL Comp-6-Format) 
Autor: eierlein
Datum: 26.11.18 17:16

Versuch mal Encoding.Default oder Encoding.GetEncoding(1252)
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Hexwert in String Halbbyte für Halbbyte umwandeln (COBOL Comp-6-Format) 
Autor: Schudi
Datum: 26.11.18 18:30

Encoding.Default und Encoding.GetEncoding(1252) bringen beide exakt dasselbe Ergebnis: "1921221018"

t1 = Chrw(25) & "TM" & Chrw(16) & Chrw(24) (Ergebnis des ReadChars(4))

Dez 25 = hex"19" passt
Dez ?? = hex "2122" pass nicht
Dez 16 = hex "10" passt
Dez(24) = hex "18" passt

also 2122 statt 99

Wie gesagt, geschrieben wurden die Daten in Ascii.
Am Besten passt die "alte" Ms-Dos-Codeseite 850, also Encoding.Getencoding(850)...
Dann kommt an Stelle der 99 das "Ö", welches den Hexcode "99" in der Ascii-Tabelle hat...

Nur bei e = e & Convert.ToInt32(GetChar(t1, i)).ToString("X2") wird aus dem "Ö" dann "D6" statt "99"...


Wie meintest Du das:

eierlein schrieb:
Zitat:

Nimm ChrW statt Chr.

Dann klappt's auch mit Werten > 127 (7F hex)


Ich weiß nicht wo ich da ChrW nehmen soll. "GetChrW" gibt es leider nicht...
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Hexwert in String Halbbyte für Halbbyte umwandeln (COBOL Comp-6-Format) 
Autor: eierlein
Datum: 26.11.18 19:47

Vergiss das ChrW.
Wenn ich den Teststring mit ChrW erstellt habe klappte es.

Allerdings konvertiert .net alle Zeichen in UTF16LE

Mit ReadBytes statt ReadChars sollte es klappen.

Beispiel auf Basis von Kuno:

Structure Artikel
        Dim Mc As String '10 Byte
 
        Dim Num() As Byte  'Byte Array ohne Anzahl-Angabe
 
        Dim Bez As String '10 Byte
        Dim Vki As Integer '4 Byte
        Dim AnzVol As Integer '4 Byte
        Dim AnzLer As Integer '4 Byte
    End Structure
 
    Sub LeseDatei()
 
        Dim s = IO.File.OpenRead("d:\##\cobol.txt")  'Testdatei
        Dim r = New IO.BinaryReader(s)
        Dim x As String = "" 
        Dim i As Integer
 
        'einen Satz lesen
        Dim a As New Artikel
        a.Mc = r.ReadChars(10)
 
'###################################################################
 
        a.Num = r.ReadBytes(2)   '<--- Anzahl Bytes anpassen
        For i = 0 To a.Num.Length - 1   ' Arrays fangen mit 0 an
            x &= a.Num(i).ToString("X2")  ' als string
        Next
        i = Convert.ToInt16(x) ' in Integer Zahl konvertieren
'###################################################################
 
        a.Bez = r.ReadChars(10)
        a.Vki = r.ReadInt32
        a.AnzVol = r.ReadInt32
        a.AnzLer = r.ReadInt32
 
        r.Close()
 
        Debug.Print("Num-String   : " & x)
        Debug.Print("Num-Zahl     : " & i.ToString)
Falls es Texte mit Umlauten (Zeichen > 127) gibt, brauchst du ein encoding.

Beitrag wurde zuletzt am 26.11.18 um 19:51:27 editiert.
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Hexwert in String Halbbyte für Halbbyte umwandeln (COBOL Comp-6-Format) 
Autor: Schudi
Datum: 26.11.18 20:51

Danke, danke, danke!

100 Punkte mit Sternchen!

Funktioniert mit allen bisher probierten Werten. 115 / 20150423 / 19991018

Ich hab's nur noch verallgemeinert:

    Structure Artikel
        Dim Mc As String '10 Byte
        Dim Num As Integer '2 Byte
        ...
        Dim NeuDat As String '4 Byte
        ...
    End Structure
 
    Sub LeseDatei()
 
        Dim s = IO.File.OpenRead("d:\##\cobol.txt")  'Testdatei
        Dim r = New IO.BinaryReader(s)
 
        'einen Satz lesen
        Dim a As New Artikel
 
        ReadBuffer = r.ReadBytes(2)
        a.Num = CType(Comp6toString(ReadBuffer), Integer)  'inkl. Umsetzung 
        ' nach Integer
 
        ...
 
        ReadBuffer = r.ReadBytes(4)
        a.NeuDat = Comp6toString(ReadBuffer)               'bleibt eine String
 
        ...
 
        r.Close()
 
    End Sub
   Public Function Comp6toString(ReadValue() As Byte) As String
 
        Dim x As String = ""
        For i = 0 To ReadValue.Length - 1
            x &= ReadValue(i).ToString("x2")
        Next
        Return x
 
    End Function
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Sie sind nicht angemeldet!
Um auf diesen Beitrag zu antworten oder neue Beiträge schreiben zu können, müssen Sie sich zunächst anmelden.

Einloggen  |  Neu registrieren

Funktionen:  Zum Thema  |  GesamtübersichtSuchen 

nach obenzurück
 
   

Copyright ©2000-2024 vb@rchiv Dieter Otter
Alle Rechte vorbehalten.
Microsoft, Windows und Visual Basic sind entweder eingetragene Marken oder Marken der Microsoft Corporation in den USA und/oder anderen Ländern. Weitere auf dieser Homepage aufgeführten Produkt- und Firmennamen können geschützte Marken ihrer jeweiligen Inhaber sein.

Diese Seiten wurden optimiert für eine Bildschirmauflösung von mind. 1280x1024 Pixel