TIA Datenkonvertierung 8bit zu 6bit zu Hex

daloeff

Level-1
Beiträge
59
Reaktionspunkte
4
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo Leute,

ich stehe gerade ziemlich auf der Leitung, vielleicht könnt ihr mir helfen.

Die Vorgabe ist bei einen STRING mit 19 Zeichen, bei jedem Zeichen 2 Bits rauszuschneiden und durch die Lücke sollten die anderen Bits nachrücken. Anschließend sollten die nun wieder vollständigen Bytes in Hex in einen STRING mit 16 Zeichen übergeben werden.
Hintergrund ist, dass die 19 Bytes vom String auf 16 Bytes gekürzt werden, da diese auf einen RFID geschrieben werden sollen. Jedoch ist es meiner Ansicht nach falsch, da wir hier Informationen entfernen, die im Nachhinein nicht wieder hergestellt werden können.

Ich habe ein Beispiel angehängt wie es aussehen sollte:
2021-03-16 14_30_22-KONVERZE 6bit na 8bit DM code.docx - Word.jpg

Ich habe gedacht, ich zerlege den String in einen Array of Bytes und splitte diesen mit Scatter_Blk auf einen Array mit bools. Anschließend die Bools bearbeiten, verschieben, was auch immer. Mit Gather_Blk wieder zurück in Array of Bytes und anschließend den Array mit HTA (Hex to Ascii) die Hex zeichen in den String zurück bringen.
Leider habe ich jedoch keinen Erfolg mit meiner Methode. Es will einfach nicht klappen mit den Bits löschen und verschieben...

Wie würdet Ihr hier vorgehen?

Danke!
 
kann es sein dass hier nach ISO 17363-17367 kodiert werden soll?
https://www.vda.de/dam/vda/publicat...id-einsatz-in-der-automobilindustrie-v1-2.pdf

Die Dateninhalte des UII inklusive Referenz-ID werden 6-bit kodiert, d. h., es gilt die reguläre 6-bit Kodierung für die Darstellung von Buchstaben, Zahlen und Sonderzeichen. Folglich dürfen ausschließlich Großbuchstaben und eine eingeschränkte Menge von Sonderzeichen verwendet werden (siehe ISO/IEC 15962). Die Kodierungsvorschrift kann dem Anhang (Tabelle 17) entnommen werden.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Das Thema HEX, HEX TO ASCII, ... bitte ausklammern! Das führt für mein (noch nicht so wirklich vorhandenes) Verständnis in die Wüste.
Das Thema STRING kann in diesem Zusammenhang auch problematisch sein und zu Missverständnissen führen.

Das angehängte Beispiel sagt mir leider nicht sehr viel. Ist das eine Vorschrift, an Du Dich halten sollst oder ein von Dir ausgeknobelter LösungsAnsatz?

Wenn die ungepackten Bytes immer z.B. and den Positionen der beiden höchstwertigen Bits 0 enthalten, kannst Du diese eliminieren durch "ZusammenSchieben", ohne dadurch Informationen zu verlieren.
Ich würde das Packen und Entpacken in DoppelWorten ausführen. (Evtl. FCs dafür schaffen?)

DWORD mit 4 ungepackten Bytes (4 Zeichen zu je 8 Bits) laden. Dann maskieren, schieben, zusammenODERn u.s.w. und zuletzt 3 Bytes Ergebnis (4 Zeichen zu je 6 Bits) rausholen.
Das gleiche 4-mal wiederholen, also 20 Bytes zu 15 Bytes packen. Was Du dann mit dem 16. (ungenutzten) Byte der gepackten Information machst ... keine Ahnung.

Umgekehrt, DWORD mit 3 gepackten Bytes laden und wieder maskieren, schieben, zusammenODERn u.s.w. und zuletzt das Ergebnis von 4 entpackten Bytes entnehmen.
Das gleiche 4-mal wiederholen für die weiteren.

Statt zu schieben, könnte man auch dividieren (inkl. MOD) und multiplizieren ... wenn nicht das verflixte 31. Bit wäre, das bei der Bearbeitung als DINT stört.

- Erzähl mal bitte, welche ungepackten Zeichen angeliefert werden. Werte von ... bis ... ? (hier darfst Du auch eine HEX-Darstellung wählen)

- Sollen die Zeichen linksbündig oder rechtsbündig zusammen geschoben werden?
 
Oberchefe hat den Nagel auf den Kopf getroffen.
Es handelt sich um eine Konvertierung nach "6-Bit-Encoding (ISO 17363-17367)"
Wie im PDF beschrieben...
Hier müsste es doch einen fertigen Baustein oder eine Umwandlung geben?

Im Internet findet sich leider nichts... Also siehts so aus als müsste man es tatsächlich selbst Ausprogrammieren...
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Huch, mein Beitrag ist anscheinend irgendwo im Netz hängengeblieben, nachdem es sich dort verlaufen hatte!? ;)
Also nochmal, aber diesmal nur in KurzForm.

Das Umwandeln würde ich über eine Tabelle mit 64 Zeilen und 2 Spalten realisieren.
ZeilenNr alias -Index: die lückenlos belegten 6BitCodes 0..63.
Spalte 1: der zum Index (dem 6BitCode) passende 8BitCode (z.Z. Werte 0 [SUP]1[/SUP]) .. 93 bzw. 4..93, nicht lückenlos belegt).
Spalte 2: Index, der mit doppeltindirekter Adressierung einen Zugriff auf den 8BitCode in der Reihenfolge "nach 8BitCode und 6-BitCode sortiert [SUP]2[/SUP])" erlaubt.

Die Schiebereien (Einfügen bzw. Eliminieren von zwei 0-Bits) sind trotz Tabelle beizubehalten. Es werden jedoch ausschliesslich 6-BitCodes geschoben.

Zur Wandlung von 8- in 6-BitCodes die vier 8-BitCodes in Tabelle binär suchen und zugehörigen 6-BitCode lesen und in "SchiebeRegister" eintragen.
SchiebeRegister "komprimieren" und Ergebnis (= 3 Bytes) auslesen.

Zur Wandlung von 6- in 8-BitCodes 3 Bytes 6-BitCode ins SchiebeRegister eintragen.
SchiebeRegister "expandieren" und danach noch das ZwischenErgebnis (4 Bytes mit den vier 6-BitCodes) byteweise via Tabelle in die entsprechenden 8-BitCodes wandeln.

Zu [SUP]1[/SUP]) :
Für die "Reserved"-8BitCodes würde ich 0 eintragen.

Zu [SUP]2[/SUP]) :
Gilt bis die 64 Zuordnungen keine "Reserved"-8BitCodes mehr enthalten.
Wenn keine "Reserved" mehr eingetragen sind, genügt Sortierung nach 8BitCode.

Edit:
Oberchefe hat mich mit #7 überzeugt, Tabelle wäre in diesem Fall nicht sinnvoll. Ich hatte vor lauter Nullen und Einsen die BinärZahlen nicht mehr (richtig) gesehen! :ROFLMAO:
 
Zuletzt bearbeitet:
So ungefähr könnte das aussehen:
Code:
FUNCTION "StringtoRFID" : Bool
{ S7_Optimized_Access := 'FALSE' }
VERSION : 0.1
   VAR_INPUT 
      sInString : String;
   END_VAR

   VAR_IN_OUT 
      abyResult : Array[0..29] of Byte;
   END_VAR

   VAR_TEMP 
      iOutLoop : Int;
      iInnLoop : Int;
      iNrChars : Int;
      byResult : Byte;
      abResult AT byResult : Array[0..7] of Bool;
      abTemp : Array[0..299] of Bool;
      sTempString : String[40];
      abByteView AT sTempString : Array[0..41] of Byte;
      diLoopMax : DInt;
   END_VAR


BEGIN
    #StringtoRFID := TRUE;
    
    #sTempString:=#sInString;
    
    #iNrChars := LEN(#sTempString);
    
    FOR #iOutLoop := 0 TO #iNrChars - 1 DO
        CASE BYTE_TO_DINT(#abByteView[#iOutLoop + 2]) OF
            32: //Space
                #byResult := 32;
            4:  //EOT
                #byResult := 33;
            28: //FS
                #byResult := 35;
            31: //US
                #byResult := 36;
            40..63:
                #byResult := #abByteView[#iOutLoop + 2];
            64..93:
                #byResult := #abByteView[#iOutLoop + 2] - 64;
            29: //GS
                #byResult := 30;
            30: //RS
                #byResult := 31;
            ELSE:
                #StringtoRFID := FALSE;
        END_CASE;
    
        FOR #iInnLoop := 0 TO 5 DO
            #abTemp[(#iOutLoop * 6) + #iInnLoop] := #abResult[5 - #iInnLoop];
        END_FOR;
    END_FOR;
    
    IF #iNrChars < 40 THEN
        #byResult := 2#100001;  //End Of Transmission
        FOR #iInnLoop := 0 TO 5 DO
            #abTemp[(#iNrChars * 6) + #iInnLoop] := #abResult[5 - #iInnLoop];
        END_FOR;
        
        #byResult := 2#100000;  //Bit Padding, pauschal 3 "Zeichen" anhängen
        FOR #iOutLoop := 0 TO 2 DO
            FOR #iInnLoop := 0 TO 5 DO
                #abTemp[((#iNrChars + 1 + #iOutLoop) * 6) + #iInnLoop] := #abResult[5 - #iInnLoop];
            END_FOR;
        END_FOR;
    ELSE
        #byResult := 2#100000;  //Bit Padding, pauschal 3 "Zeichen" anhängen
        FOR #iOutLoop := 0 TO 2 DO
            FOR #iInnLoop := 0 TO 5 DO
                #abTemp[((#iNrChars + #iOutLoop) * 6) + #iInnLoop] := #abResult[5 - #iInnLoop];
            END_FOR;
        END_FOR;
    END_IF;
    
    
    
    #diLoopMax := (#iNrChars * 6) / 8;
    IF (#diLoopMax * 8) / 6 <> #iNrChars THEN   //muss aufgerundet werden?
        #diLoopMax := #diLoopMax + 1;
    END_IF;
    
    IF #diLoopMax <> (#diLoopMax / 2) * 2 THEN  //Ungerade Anzahl?
        #diLoopMax := #diLoopMax + 1;
    END_IF;
    
    FOR #iOutLoop := 0 TO #diLoopMax - 1 DO
        FOR #iInnLoop := 0 TO 7 DO
            #abResult[#iInnLoop] := #abTemp[#iOutLoop * 8 + (7 - #iInnLoop)];
        END_FOR;
        #abyResult[#iOutLoop] := #byResult;
    END_FOR;
    
    
    
END_FUNCTION
 
Zurück
Oben