Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   xor Verknupfungen (https://www.delphipraxis.net/210336-xor-verknupfungen.html)

js747a 7. Apr 2022 14:18

xor Verknupfungen
 
An alle Delphi User die sich mit xor Verknupfungen auskennen.

zunächst muss ich mal diesen Satz in Delphi umsetzen.

Im LOCONET Protokol steht das
Die Daten-Bytes auf dem LocoNet® sind als 8-Bit-Daten definiert, die mit dem als letztes Bit im Oktett übertragenen höchstwertigen Bit (ms) eine Befehlscode-Markierung (OPCODE) erhalten. Wenn das ms-Bit (D7) 1 ist, werden die 7 geringwertigeren Bits als Netzwerk-OPCODE interpretiert. Dieses OPCODE-Byte ist immner nur einmal in einer gültigen Nachricht enthalten und ist das erste Byte einer Nachricht. In allen überigen Bytes der Nachricht muss inklusive des letzten Prüfsummenbytes (CHECKSUM) das höchstwertige Bit auf 0 gesetzt sein. Die CHECKSUM ist das Einer-COMPLEMENT eines Exclusiv-Oder über alle Bytes der Nachricht, außer der CHECKSUM selbst. Um die Datengenauigkeit zu prüfen, sind alle Bytes einer korrekten Nachricht exclusiv-oder-verknüpft. Wenn der resultierende Wert hexadezimal “FF” ist, werden die Daten als richtig akzeptiert.

mein Versuch

Dieses OPCODE-Byte ist immner nur einmal in einer gültigen Nachricht enthalten und ist das erste Byte einer Nachricht.

OPCODE 0x83 also z.B.

OPCODE ; Byte;
OPCODE := 130; //0x83

Die CHECKSUM ist das Einer-COMPLEMENT eines Exclusiv-Oder über alle Bytes der Nachricht

CheckByte ,Checksum : Byte;
CheckByte := $00;
Checksum := OPC_GPON xor CheckByte;


Senden
InterfacePort.WriteStr(Chr(OPCODE )+Chr(Checksum));

Blup 8. Apr 2022 12:51

AW: xor Verknupfungen
 
Mit Chr und String währe ich aber vorsichtig. Die Umwandlung aus deiner Bytefolge etwas ganz anderes machen als erwartet.
Hier währe TBytes als Buffer(für die zu übertragene Bytefolge) und eine Funktion die direkt eine Bytefolge überträgt sinnvoller.
Delphi-Quellcode:
function BuildCommand(ACommand: Byte; AData: const array of Byte): TBytes;
var
  CheckSum, B: Byte;
begin
  SetLength(Result, 2 + Length(AData));
  CheckSum := ACommand;
  Result[0] := ACommand;
  for var n := 0 to High(AData) do
  begin
    B := AData[n];
    CheckSum := CheckSum xor B;
    Result[1 + n] := B;
  end;
  Checksum := CheckSum xor $FF;
  Result[High(Result)] := CheckSum;
end;

Uwe Raabe 8. Apr 2022 13:08

AW: xor Verknupfungen
 
Zitat:

Zitat von Blup (Beitrag 1504449)
Mit Chr und String währe ich aber vorsichtig. Die Umwandlung aus deiner Bytefolge etwas ganz anderes machen als erwartet.
Hier währe TBytes als Buffer(für die zu übertragene Bytefolge) und eine Funktion die direkt eine Bytefolge überträgt sinnvoller.

Wenn es hier wirklich um Delphi 7 geht, ist das vermutlich nur halb so schlimm. Da würde es dann auch kein TBytes geben.

Und sollte dies
Delphi-Quellcode:
function BuildCommand(ACommand: Byte; AData: const array of Byte): TBytes;


nicht eher so aussehen?
Delphi-Quellcode:
function BuildCommand(ACommand: Byte; const AData: array of Byte): TBytes;

js747a 9. Apr 2022 13:37

AW: xor Verknupfungen
 
Hallo, erstmal Danke für die Antworten.
Aber wie kann ich das ohne die TByte machen.
In Delphi 7



function BuildCommand(ACommand: Byte; AData: const array of Byte): TBytes;
var
CheckSum, B: Byte;
begin
SetLength(Result, 2 + Length(AData));
CheckSum := ACommand;
Result[0] := ACommand;
for var n := 0 to High(AData) do
begin
B := AData[n];
CheckSum := CheckSum xor B;
Result[1 + n] := B;
end;
Checksum := CheckSum xor $FF;
Result[High(Result)] := CheckSum;
end;

Wenn ich das Richtig verstehe dann ..


wenn ich nur 2 Byte sende.

Ein TByte ist also ein Array of Bytes.
- CheckSum := ACommand; ist OPCODE 0x83
- Result[0] := ACommand; ist das erste im Array also bei mit OPCODE 0x83
- Checksum := CheckSum xor $FF;
- Result[1] := Checksum ;
InterfacePort.WriteStr(Chr(Result[0])+Chr(Result[1]));


wenn ich mehr als 2 Byte sende.

- CheckSum := ACommand; ist OPCODE 0x83
- Result[0] := ACommand; ist das erste im Array also bei mit OPCODE 0x83

dann wird für jedes Byte in AData
- B = n Byte in AData
- CheckSum := CheckSum xor B;
- Result[n] = B

- Checksum := CheckSum xor $FF;
- Result[High(Result)] := CheckSum; - Letzte Byte in Result := CheckSum
InterfacePort.WriteStr(Chr(Result[0])+Chr(Result[n])+Chr(Result[n]));

KodeZwerg 9. Apr 2022 21:05

AW: xor Verknupfungen
 
Zitat:

Zitat von js747a (Beitrag 1504465)
Aber wie kann ich das ohne die TByte machen

Gar nicht. Aber definiere es einfach selbst und fertig ist.
Delphi-Quellcode:
type
  TBytes = array of Byte;

Kurt Wallander 13. Apr 2022 12:04

AW: xor Verknupfungen
 
Hi
ich habe zu deinem Problem ein paar Fragen. Wieviel Byte umfaßt ein Datentransfer?
die dezimale Darstellung von 0x83 ist 131 anstatt 130.
Ein Checkbyte mit 0x00 zu belegen und ein anderes Byte (OP...) mit xor Checkbyte zu verknüpfen macht keinen Sinn: es kommt als Ergebnis wieder OP... heraus.
Du mußt also Byte1 xor Byte2 xor Byte3 ... bilden.
Falls das höherwertige bit des Bytex den wert 1 hat (Bytex>=128 oder Bytex>=0x80) sollen nur die niederwertigen Bytes berücksichtigt werden: Bytex and 0x7F bzw Bytex and 127.
Die Checksumme ist zum Schluß bitweise zu negieren: CheckSum:= not (Ergebnis aller xor-Verknüpfungen)
Good luck


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