String Character ASCII nach ANSI Konvertierung

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 8 Antworten in diesem Thema. Der letzte Beitrag () ist von roepke.

    String Character ASCII nach ANSI Konvertierung

    Ich nutze die FTDI FT2XX_NET.dll um Daten via USB aus einem angeschlossenen Gerät zu lesen.
    Dabei gibt es mehrere Möglichkeiten die Daten aus dem Empfangspuffer zu holen.

    FTDI.Read(byte[] dataBuffer, UInt32 numBytesToRead, ref UInt32 numBytesRead)

    bzw.

    FTDI. Read(out string dataBuffer, UInt32 numBytesToRead, ref UInt32 numBytesRead)

    I.d.R. nutze ich einen String als dataBuffer, da die Daten als ASCII Zeichen vorliegen.
    Über die empfangenen Daten bilde ich zeichenweise eine simple XOR Prüfsumme

    VB.NET-Quellcode

    1. Dim _iChecksum As Integer = 0
    2. For Each _Char In dataBuffer
    3. _iChecksum =_iChecksum Xor Convert.ToUInt32(_Char)
    4. Next
    5. Return _iChecksum.ToString("X2")


    Es gibt einen einzigen Fall, in dem ich die Daten nicht als ASCII, sondern (mutmaßlich, zumindest behauptet das Notepad++) als ANSI bekomme. Es handelt sich dabei um eine komprimierte Textdatei. Diese wird nicht entpackt sondern so wie sie ist die Prüfsumme darüber gebildet. Hierbei schlägt jetzt meine Prüfsummenbildung fehl, weil für Zeichen mit einem gesetzten MSB keine Entsprechung im ASCII String möglich ist. Es kommt zu keiner Fehlermeldung, aber die Prüfsumme ist am Ende falsch, weil z.B. 0x8B als 0x3F interpretiert wird.

    Daher nutze ich an dieser Stelle den byte[] dataBuffer und

    VB.NET-Quellcode

    1. Dim _btIntChecksum As Byte = 0
    2. For _i As Integer = 0 To dataBuffer.Length
    3. _btChecksum = _btChecksum Xor dataBuffer(_i)
    4. Next
    5. Return Convert.ToString(_btIntChecksum, 16)).ToUpper


    zur Prüfsummenbildung.

    Das ist nicht so schick, weil ich die beiden Möglichkeiten unterscheiden muss.
    Gibt es denn nicht eine Möglichkeit auf das Auslesen der empfangene Daten als byte[] Array zu verzichten und die einzelnen Zeichen des String so umzuwandeln, dass sie nicht als ASCII (max. 07F) sondern als Zeichen bis 0xFF zu verstehen sind?
    Was Encodings angeht, vielleicht sind hier schon nützliche Dinge dabei.
    Probleme mit ANSI

    Kann es sein, dass die Variablen nicht richtig benamt sind (btIntCheckSum btCheckSum) in Snippet2?
    Vielleicht hast du ein paar Beispiel-Werte zum Lesen für uns? Also ein Wert, der dir keine Probleme macht und einer, der dir Probleme macht.
    @roepke Bytes kannst Du so in einen String konvertieren:

    C#-Quellcode

    1. // = "keys.key";
    2. byte[] letters = new byte[] { 0x6B, 0x65, 0x79, 0x73, 0x2E, 0x6B, 0x65, 0x79 };
    3. string name = System.Text.Encoding.Default.GetString(letters);
    Verwende dabei Dein spezielles Encoding.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „RodFromGermany“ ()

    @Haudruferzappeltnoch hast recht, btIntCheckSum = btCheckSum, mein Fehler.

    Ich bin jetzt letzte Nacht noch mal in mich gegangen und kam zum Schluss, dass mein Vorhaben wohl zum Scheitern verurteilt ist.
    Grund: wenn ich Daten mittels des ersten Snippets lese, bekomme ich einen String.
    Alle darin enthaltenen Zeichen sind ASCII, d.h. max. 0x7F.
    Enthalten die zu lesenden Daten aber z.B. 0x8A, kann das im String nicht abgebildet werden.
    Daher wird an dieser Stelle 0x3F (?) eingetragen. Es ist also nicht möglich diesen String in Byte() zu wandeln und an der entsprechenden Stelle wieder das 0x8A zu bekommen.
    Umgekehrt kann ich aus Byte() aber auch keinen sinnvollen String erzeugen, weil dort eben alles über 0x7F zu 0x3F wird.
    Da ich in 99,9% aller Fälle einen ASCII String lese und benötige und nur in einem einzigen Fall Zeichen außerhalb ASCII vorkommen können, werde ich wohl die bisherige „Zweiwegelösung“ beibehalten und in diesem einen speziellen Fall Snippet 2 zum lesen verwenden.

    roepke schrieb:

    Es ist also nicht möglich diesen String in Byte() zu wandeln und an der entsprechenden Stelle wieder das 0x8A zu bekommen
    Wie schon im Link gezeigt, konvertieren an sich geht, das wär ja auch quatsch wenn nicht, der Computer arbeitet nur mit Bits.

    Die Convert.ToUInt32 konvertiert Unicode Zeichen, deswegen kriegst da Müll raus. CInt("‹"c) ergibt aber 139 und CChar(139) "‹"c
    Convert.ToUInt32 macht da 8249 draus.
    Das liegt daran, dass das Zeichen ‹ in Unicode an ganz anderer Stelle steht als in ANSI.
    Ah, sieh an, wieder was gelernt.
    Ändert aber leider auch nichts an der Tatsache, dass in meinem empf. String für Zeichen außerhalb ASCII 0x3F(?) steht, was eine Umwandlung in Byte nicht ermöglicht.
    Aus diesem Grund gibt es vermutlich auch die Möglichkeit die Daten direkt als Byte abzuholen.
    @roepke Was sagt denn die Gerätebeschreibung, was da gesendet wird?
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    roepke schrieb:

    in meinem empf. String für Zeichen außerhalb ASCII 0x3F(?) steht
    Das Gerät schickt immer Bytes bzw. Strom.
    Dann musst du auf deine Empfangsmethode schauen, wie du das einliest, was da kommt.
    Da hast du dann schon das falsche Encoding.
    Also diese dll Methodenüberladung macht das ja scheinbar, kann man da kein Encoding angeben? Dann bist du auf das ByteArray angewiesen und musst selbst konvertieren.
    Dann würde ich das auch immer machen, auch bei ASCII Input.
    Das ist die D2XX.DLL von FTDI mit einem zusätzlichen FTD2XX_NET.dll Wrapper. Der Wrapper ist als Quelle verfügbar und dadurch ganz gut dokuemntiert. Die D2XX.DLL hingegen ist eine Blackbox. Ich könnte den Wrapper natürlich mit einer zusätzlichen Read() Funktion überladen und mir diese so zurecht bauen, dass die Daten ganau so zurückkommen wie ich sie brauche. Das wäre jetzt erst mal mein Lösungsansatz.