AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Dekodierer für Nachrichten

Ein Thema von benwen · begonnen am 15. Mär 2013 · letzter Beitrag vom 19. Mär 2013
Antwort Antwort
Seite 1 von 2  1 2      
benwen

Registriert seit: 11. Sep 2006
17 Beiträge
 
Delphi 7 Enterprise
 
#1

Dekodierer für Nachrichten

  Alt 15. Mär 2013, 10:40
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
  Mit Zitat antworten Zitat
Benutzerbild von p80286
p80286

Registriert seit: 28. Apr 2008
Ort: Stolberg (Rhl)
6.659 Beiträge
 
FreePascal / Lazarus
 
#2

AW: Dekodierer für Nachrichten

  Alt 15. Mär 2013, 12:17
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
Programme gehorchen nicht Deinen Absichten sondern Deinen Anweisungen
R.E.D retired error detector
  Mit Zitat antworten Zitat
Benutzerbild von Aphton
Aphton

Registriert seit: 31. Mai 2009
1.198 Beiträge
 
Turbo Delphi für Win32
 
#3

AW: Dekodierer für Nachrichten

  Alt 15. Mär 2013, 12:28
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!
das Erkennen beginnt, wenn der Erkennende vom zu Erkennenden Abstand nimmt
MfG
  Mit Zitat antworten Zitat
benwen

Registriert seit: 11. Sep 2006
17 Beiträge
 
Delphi 7 Enterprise
 
#4

AW: Dekodierer für Nachrichten

  Alt 15. Mär 2013, 13:10
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!
  Mit Zitat antworten Zitat
Benutzerbild von BUG
BUG

Registriert seit: 4. Dez 2003
Ort: Cottbus
2.094 Beiträge
 
#5

AW: Dekodierer für Nachrichten

  Alt 15. Mär 2013, 13:24
Also ich würde mir als erstes etwas wie einen Bit-Stream Programmieren.

Delphi-Quellcode:
type BitReader = class
  contructor create(source: TStream);
  /** Gibt die nächsten amount Bits als Ganzzahl zurück. */
  function readBits(amount: byte): cardinal;
end;
An dieser Klasse lässt sich dann gut rumoptimieren ohne dein Programm durcheinander zu bringen.

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.
Intellekt ist das Verstehen von Wissen. Verstehen ist der wahre Pfad zu Einsicht. Einsicht ist der Schlüssel zu allem.
  Mit Zitat antworten Zitat
Benutzerbild von Aphton
Aphton

Registriert seit: 31. Mai 2009
1.198 Beiträge
 
Turbo Delphi für Win32
 
#6

AW: Dekodierer für Nachrichten

  Alt 15. Mär 2013, 13:32
Zitat:
Ich bekomme die Nachricht als Bytestring, also z.B
Nachricht 1: a01b48768e9ff9
Nachricht 2: 46a57b8c94aa2332
...
Nun da hast du wieder eine 200% Redundanz drinnen. Als Byte-Hex belegt man 2 Bytes für ein Byte an Daten. Dh die Zahlen 0..255 werden intern als 1 Byte abgespeichert, aber als HexString benötigt man 2 Zeichen, wo pro Zeichen ein Byte verwendet wird - also 2 Byte.

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!).
das Erkennen beginnt, wenn der Erkennende vom zu Erkennenden Abstand nimmt
MfG
  Mit Zitat antworten Zitat
gammatester

Registriert seit: 6. Dez 2005
999 Beiträge
 
#7

AW: Dekodierer für Nachrichten

  Alt 15. Mär 2013, 14:13
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.
Wie shiftet man den 11 mal ein Byte? Im Ernst: ein Klacks ist es erst dann, wenn auch die Bittigkeit (Endianness) geklärt ist.
  Mit Zitat antworten Zitat
Benutzerbild von Aphton
Aphton

Registriert seit: 31. Mai 2009
1.198 Beiträge
 
Turbo Delphi für Win32
 
#8

AW: Dekodierer für Nachrichten

  Alt 15. Mär 2013, 15:34
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:
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)
Hier erhält man dann 111111111000b (4088d).
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!
das Erkennen beginnt, wenn der Erkennende vom zu Erkennenden Abstand nimmt
MfG

Geändert von Aphton (15. Mär 2013 um 15:43 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von p80286
p80286

Registriert seit: 28. Apr 2008
Ort: Stolberg (Rhl)
6.659 Beiträge
 
FreePascal / Lazarus
 
#9

AW: Dekodierer für Nachrichten

  Alt 15. Mär 2013, 15:55
: ein Klacks ist es erst dann, wenn auch die Bittigkeit (Endianness) geklärt ist.
Das ist ja wohl die Grundvorraussetzung.
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
Programme gehorchen nicht Deinen Absichten sondern Deinen Anweisungen
R.E.D retired error detector

Geändert von p80286 (15. Mär 2013 um 15:55 Uhr) Grund: tonnen vonTippfehlern
  Mit Zitat antworten Zitat
Benutzerbild von Phoenix
Phoenix
(Moderator)

Registriert seit: 25. Jun 2002
Ort: Hausach
7.639 Beiträge
 
#10

AW: Dekodierer für Nachrichten

  Alt 18. Mär 2013, 07:58
Also.. wir reden hier ja von unmanaged code, da kann man ja schweinereien machen

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
Sebastian Gingter
Phoenix - 不死鳥, Microsoft MVP, Rettungshundeführer
Über mich: Sebastian Gingter @ Thinktecture Mein Blog: https://gingter.org
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:11 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz