Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi PHP to Delphi: pack() / unpack(); (https://www.delphipraxis.net/141853-php-delphi-pack-unpack-%3B.html)

xSkaschY 17. Okt 2009 17:07


PHP to Delphi: pack() / unpack();
 
Liste der Anhänge anzeigen (Anzahl: 1)
N'Abend zusammen,

Versuche gerade einen PHP in Delphi zu kopieren, jedoch scheitere ich an der pack(); mathode von PHP.

Folgend der PHP Code:

Code:
$sOutput = pack(
   "nvCCCCv",
   $this->wMagic,
   $this->wHash,
   $this->byVersion,
   $this->byPacketType,
   $this->byRequestType,
   $this->byUnknown0x00,
   $this->wFieldCount
);
Ich habe es nach einschlägiger Suche mal so probiert:

Delphi-Quellcode:
  rData := TStringStream.Create('');
  try
    rData.Position:= 0;

    rData.Write(rPacketHeader.wMagic, SIZEOF(WORD));
    rData.Write(rPacketHeader.wHash, SIZEOF(WORD));
    rData.Write(rPacketHeader.byVersion, SIZEOF(BYTE));
    rData.Write(rPacketHeader.byPacketType, SIZEOF(BYTE));
    rData.Write(rPacketHeader.byUknown0x00, SIZEOF(BYTE));
    rData.Write(rPacketHeader.wFieldCount, SIZEOF(WORD));

    if rPacketHeader.byPacketType = AA3_PACKET_TYPE_FRAGMENTED_RESPONSE then begin
      rData.Write(rPacketHeader.wOrder, SIZEOF(WORD));
      rData.Write(rPacketHeader.wTotal, SIZEOF(WORD));
    end;

    Result := rData.DataString + rPacketHeader.sData;
  finally
    rData.Free;
  end;
Aber in PHP habe ich 31 Byte, in delphi nur 30... da fehlt ein Byte! :(

Und auch der Binary String ist komplett anders:

PHP etwa: "J5ÿÿ���i<aCg+<QlMB Qn0m"

In Delphi bekomme ich nur ein "5Jÿÿ" in des TMemo.


Anbei wie das fertige Paket "ausschauen" soll.


Wie komme ich nu weiter?


LG Toby

jfheins 17. Okt 2009 17:17

Re: PHP to Delphi: pack() / unpack();
 
Du hast ja auch das eine Byte vergessen:

Byte - Unknown, appears to always have the value 0x00

xSkaschY 17. Okt 2009 23:05

Re: PHP to Delphi: pack() / unpack();
 
Hallo,

danke für deine Antwort.

Du hast recht, ich hab die Procedure Argumente etwas durcheinander gebracht. Besten dank! :)

xSkaschY 17. Okt 2009 23:18

Re: PHP to Delphi: pack() / unpack();
 
Irgendwie kommt aber immernoch nicht das richtige zustande.

Wie kann ich mir den Binary String den mal anzeigen lassen?

ShowMessage oder ein TMEmo lässt die hälfte raus.

LG

Valle 17. Okt 2009 23:22

Re: PHP to Delphi: pack() / unpack();
 
Speicher es in eine Datei und öffne sie mit einem Bei Google suchenHexeditor. ;-)

Liebe Grüße,
Valle

xSkaschY 18. Okt 2009 00:01

Re: PHP to Delphi: pack() / unpack();
 
Also irgendwas läuft da falsch...


PHP Binary String:

4A35FFFF023F023F013F693C176143671F2B3C516C4D420B51 7F026E1E306D


Delphi Binary String

4CAA7202E0F41700020E470024F81700180E4700E0F4170030 7068022C876F


Obwohl die gleichen Daten übergeben werden. Also scheint irgendwas mit dem "pack()" nicht zu stimmen.

Hier mal eine übersicht was mein Ziel ist:

AAO3 Server UDP Query

wicht 18. Okt 2009 00:15

Re: PHP to Delphi: pack() / unpack();
 
Moin,
ich bin zwar schon gut angetrunken und bin mir nicht sicher ob es hilft, aber da, wo ich mal pack() benutzt habe, habe ich den Variablen noch einen Typecast mitgegeben. Bei PHP kann man sich glaube ich nie so sicher sein, was was ist.... Naja ich hasse PHP.. bitte nicht hauen :)

xSkaschY 18. Okt 2009 00:17

Re: PHP to Delphi: pack() / unpack();
 
Nunja :-) Wie soll ich sagen. In PHP funktioniert es ja ;) Nur Delphi mag es nicht!

Ich hab die Problematik eher andersrum :D Bitte nicht hauen! :)

Valle 18. Okt 2009 00:26

Re: PHP to Delphi: pack() / unpack();
 
Eventuell musst du die Endianness umstellen. Wie das genau geht steht auf der Dokumentationsseite der PHP-Funktion. Was du brauchst ist little Endian, zumindest wenn Delphi das nicht irgendwie ändern sollte. :gruebel:

Liebe Grüße,
Valle

xSkaschY 18. Okt 2009 00:34

Re: PHP to Delphi: pack() / unpack();
 
folgende "endianness" werden benötigt:

vorzeichenloser Short-Typ (immer 16 Bit, Byte-Folge Big Endian)
vorzeichenloser Short-Typ (immer 16 Bit, Byte-Folge Little Endian)
vorzeichenloser Long-Typ (immer 32 Bit, Byte-Folge Little Endian)
vorzeichenloses Zeichen

Code:
$sOutput = pack(
   "nvCCCCv",
   $this->wMagic,
   $this->wHash,
   $this->byVersion,
   $this->byPacketType,
   $this->byRequestType,
   $this->byUnknown0x00,
   $this->wFieldCount
);
Code:
n = Magic
v = Hash
C = Version
C = PacketType
C = RequestType
C = Unkown 0x00 ($00)
v = FieldCount

----

n = vorzeichenloser Short-Typ (immer 16 Bit, Byte-Folge Big Endian)
v = vorzeichenloser Short-Typ (immer 16 Bit, Byte-Folge Little Endian)
C = vorzeichenloses Zeichen

an anderer Stelle noch

V = vorzeichenloser Long-Typ (immer 32 Bit, Byte-Folge Little Endian)

Valle 18. Okt 2009 00:43

Re: PHP to Delphi: pack() / unpack();
 
Mh, auf der Dokumentations-Seite steht:

Zitat:

Unless otherwise noted, all values are little-endian
Da das Wort Endian im gesamten Dokument nicht weiter erwähnt wude, sind also Angaben litte Endian. Dein unpack-String ("nvCCCCv") enthält allerdings eine Mischung aus Big und Little Endian. "n" ist Big Endian, daher also glaube ich falsch. "C" hat eigenartiger Weise keine Endianness, was mich gerade ziemlich verwirrt.

Hast du die empfangenen Daten mal ausgewertet? Welche davon sind denn realtistisch ( = wahrscheinlich richtig)?

Liebe Grüße,
Valle

himitsu 18. Okt 2009 00:52

Re: PHP to Delphi: pack() / unpack();
 
C dürfte ein Byte sein, also wäre das Endianness dort wohl auch egal :angel:

xSkaschY 18. Okt 2009 01:00

Re: PHP to Delphi: pack() / unpack();
 
Naja. Das problem ist, das Protocol reagiert nicht auf falsche Daten. Sprich ich bekomme nichts zurück.

Habe gerade mal etwas gegoogelt und bin auf folgendes gestoßen:

Delphi-Quellcode:
function ChangeEndian16(X: WORD): WORD; register; //oder auch Swap
asm
  xchg AL, AH
end;

Nunja, es kommt dem Resultat schon recht nähe, jedoch schrumpft der Binary String nun um 2 Bytes, was auch wieder nicht stimmen kann, weil es 31 Byte sein "müssen".

Wobei der Wert dann nicht mehr passt.

Beispiel:

["wHash"] => WORD(65535)

wird dann zu

["wHash"] => WORD(13642)


"65535" ist aber korrekt. (0x4A 0x35)

Luckie 18. Okt 2009 01:36

Re: PHP to Delphi: pack() / unpack();
 
Kan mir mal bitte jemand erklären, was man mit der Funktion macht oder wozu man sie braucht? Aus dem PHP Manual werde ich nicht ganz schlau:
Zitat:

Packt die angegebenen Argumente unter Beachtung von format in eine Binär-Zeichenkette.
Und das Beispiel verstehe ich auch nicht:
Code:
<?php
$binaerdaten = pack("nvc*", 0x1234, 0x5678, 65, 66);
?>
Soll ergeben:
Code:
0x12, 0x34, 0x78, 0x56, 0x41, 0x4

xSkaschY 18. Okt 2009 01:41

Re: PHP to Delphi: pack() / unpack();
 
Die Funktion packt alle möglichen Daten in ein Binary String.

Sprich, word, byte, string, integer usw to Binary unter berücksichtigung verschiedener "pack-formate".

himitsu 18. Okt 2009 01:42

Re: PHP to Delphi: pack() / unpack();
 
du gibst der Funktion z.B. einzelne Variablen/Konstanten

und die Funktion macht daraus einen Binärstrom

#$12#$34#$78#$56#$41#$4

[edit]
zwei Dumme - ein Gedanke :lol:

Luckie 18. Okt 2009 01:46

Re: PHP to Delphi: pack() / unpack();
 
:gruebel:

Hm, und wann braucht man so was?

xSkaschY 18. Okt 2009 01:52

Re: PHP to Delphi: pack() / unpack();
 
Wenn man zum Beispiel, wie in meinem Fall, eine Anfrage per UDP Sockets an einen Server schickt und bestimmte Daten auswerten möchte.

wicht 18. Okt 2009 01:54

Re: PHP to Delphi: pack() / unpack();
 
Ich habe es z.B. mal benutzt, um mit einem HTTP-Request zwei Dateien abzuholen. Erst die beiden Integers für die Länge an den Anfang schreiben und dann die beiden Dateien.

Doofer roter Kasten. Aber mein Mitteilungsbedürfnis zwingt mich zu posten...

Luckie 18. Okt 2009 01:57

Re: PHP to Delphi: pack() / unpack();
 
Wohl wieder eine dieser Funktionen, die einem nicht einfällt, wenn man sie braucht. :?

xSkaschY 18. Okt 2009 02:02

Re: PHP to Delphi: pack() / unpack();
 
Wpo du Recht hast, hast du Recht! :D


Okay, also folgendes hab ich bisher erreicht:

Mit SWAP() komm ich auf den Big Endian "modifier v bei pack();".

Little Endian: 0x4A 0x35
Big Endian: 0x35 0x4A

Wer sich so etwas ausdenkt, gehört gesteinigt!

Naja, wie dem auch sei.. dann wäre da noch die Sache mit den 16bit Short-Typ und 32 bit Long-Typ, da hab ich im Forum folgendes gefunden:

Delphi-Quellcode:

function ChangeEndian16(X: WORD): WORD; register; //oder auch Swap
asm
  xchg AL, AH
end;

function ChangeEndian32(X: DWORD): DWORD; register;
asm
  bswap EAX //konvertiert Endian
end;


Mal schauen wie weit ich damit komme! :)


Alle Zeitangaben in WEZ +1. Es ist jetzt 07:19 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