![]() |
Dekodierer für Nachrichten
Verwendete Version: Delphi XE3
Hallo zusammen, hoffe ich bekomme hier eine Antwort auf meine Frage: Ich habe Nachrichten, die aus Paketen und Variablen bestehen und zu dekodieren sind. Die Paketinhalte (zusammengefasste Variablensequenznen) und Variablenlängen (z.B. Variablenlänge = 5 bit) sind spezifiziert. Alle Variablenwerte werden zunächst als Dezimalzahl interpretiert. Momentane Vorgehensweise: Bsp für Nachricht: 00101010101010101011110110.... 1. Paket lesen Variable 1 = 7bit: 0010101 -> 21 Variable 2 = 3 bit: 010 -> 2 usw. Das funktioniert soweit ganz gut, aber da die Nachrichten deutlich länger sind als im dargestellten Beispiel und es Millionen von zu dekodierenden Nachrichten sind hätte ich gerne eine optimierte/schnellere Variante. Gibt es da eine in Delphi? Allgemein finde ich die bisherige String-basierte Variante etwas unsauber/unschön. Was denkt ihr? Bin für jeden Vorschlag dankbar! Grüße ! benwen |
AW: Dekodierer für Nachrichten
Wie liegen Deine Nachrichten denn vor?
kommen da einzelne Bits vorbei oder werden wirklich Nullen und Einsen genutzt? Im ersten Falle denke ich and Assembler und die entsprechenden Shift-Befehle, im zweiten würde ich einen BytetoBit-Übersetzer bauen. Gruß K-H |
AW: Dekodierer für Nachrichten
Heißt das, die 01 Folge "00101010101010101011110110".. liegt als String vor? Warum zur Hölle macht man da eine Konvertierung in String? :|
Schau dir mal die logischen Operatoren an and, or, not und das Bitshifting: shr, shl Sollte ausreichen um zumindest ein GetBit() und SetBit() zu programmieren! |
AW: Dekodierer für Nachrichten
Ich bekomme die Nachricht als Bytestring, also z.B
Nachricht 1: a01b48768e9ff9 Nachricht 2: 46a57b8c94aa2332 ... Ich wandle jede Nachricht in einen Bitstring um und dann lese ich Variable für Variable aus dem Bitstring. Wie würde ich z.B. die ersten 12 bit auslesen bei Verwendung von Bitverschiebung? Nur ganz grob... Merci! |
AW: Dekodierer für Nachrichten
Also ich würde mir als erstes etwas wie einen Bit-Stream Programmieren.
Delphi-Quellcode:
An dieser Klasse lässt sich dann gut rumoptimieren ohne dein Programm durcheinander zu bringen.
type BitReader = class
contructor create(source: TStream); /** Gibt die nächsten amount Bits als Ganzzahl zurück. */ function readBits(amount: byte): cardinal; end; Das mit dem Speichern von Bits als 01-Strings ist das unperformanteste was man machen kann. Nicht nur das String mindestens 8-mal so viel Speicher brauchen als das direkte Arbeiten mit Bits: Meisten Stringoperationen benutzen die Speicherverwaltung und die ist in fast allen Fällen langsam. |
AW: Dekodierer für Nachrichten
Zitat:
Ist also auch unfug! Zur Frage mit 12 Bits.. Nun, die Daten liegen im Speicher vor. Will man die ersten 12 Bits lesen, so liest man Bit 0 in (z.B.) x ein, shifted x um 1 nach links und wiederholt bis man an Bit 11 angelangt ist. Du musst dir nur überlegen, wie du GetBit() & SetBit() realisiert. Alles andere ist klacks, weil es darauf dann aufbauen wird (soll!). |
AW: Dekodierer für Nachrichten
Zitat:
|
AW: Dekodierer für Nachrichten
X muss ja nicht ein Byte sein
Edit: Nun gut, man muss natürlich immer in 8er Schritten gehen bis letztendlich die Anzahl <= 8 ist, wo man dann halt das shiften braucht. Sonst kann man ja ganze Bytes nehmen! Beispiel Pseudocode
Code:
Hier erhält man dann 111111111000b (4088d).
ByteArray[0..3] = (255, 128, 0, 0) = (11111111, 10000000, 00000000, 00000000) // zB
pBytes = @ByteArray Anzahl = 12 result = 0 while Anzahl > do Result = (Result shl 8) or pBytes^ dec(Anzahl, 8) inc(pBytes) while Anzahl > 0 do Result = (Result shl 1) or (pBytes^ and 1) dec(Anzahl) Anmerkung - diese Methode startet bei 0. Man müsste es so modifizieren, dass es auch mit nem anderen Offset klappt, ich will ihm aber die Arbeit nicht wegnehmen! |
AW: Dekodierer für Nachrichten
Zitat:
Da Du irgendwann im Stream etwas Überhang haben wirst 0011 0101 0111 0000 1010 1110 Mußt Du beim Laden den vorderen und hinteren Überhang mit beachten. Wobei ich mich frage was ist mit führenden Nullen? 0 oder 0000 oder 00000000 ist als Wert immer Null. Gruß K-H |
AW: Dekodierer für Nachrichten
Also.. wir reden hier ja von unmanaged code, da kann man ja schweinereien machen :lol:
Ich würde erstmal versuchen, ein Struct (Packed Record) zu definieren, dass genau das gleiche Memory-Layout hat wie eine Nachricht. Damit braucht man eigentlich nur noch einen Pointer auf den jeweiligen Nachrichtentyp auf den Beginn der Nachricht setzen, und kann dann schon sauber drauf zugreifen. Das gibt natürlich einen Record pro Nachrichtentyp, aber der Zugriff ist dann ungeheuer bequem, und man muss nix umwandeln, umkopieren etc. Das heisst auch der Zugriff ist ziemlich flott. Ich habe auf die Art mal einen Speicherbereich den ich aus einer SPS ausgelesen habe ausgewertet. War sehr schnell und sehr zuverlässig, solange sich das Layout der Nachrichten nicht verändert ;-) |
Alle Zeitangaben in WEZ +1. Es ist jetzt 18:34 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz