Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Checksumme in einem Übertragungsprotokoll bilden (LSB) (https://www.delphipraxis.net/129272-checksumme-einem-uebertragungsprotokoll-bilden-lsb.html)

bug0815 16. Feb 2009 06:30


Checksumme in einem Übertragungsprotokoll bilden (LSB)
 
Hallo zusammen,

bei der Berechung einer Checksumme in einem Übertragungsprotokoll habe ich gerade so meine Probleme.

Hier der entsprechende Auszug aus der Schnittstellenbeschreibung:
Zitat:

The Checksum is derived by the addition of all bytes of the header, data field separators
and data fields (i.e. all characters after the stx-character, up to and including the last '/'
before the checksum field). The 8 Least Significant Bits (LSB) of the result are then
represented as two printable characters. The character containing the 4 Most Significant
Bits (MSB) (of those 8 LSB) shall be transmitted first. For example, if the checksum is 3Ahex
the representation shall be the characters '3' (33hex) and 'A' (41hex).
Die Aufsummierung der entsprechenden Bytes ergibt 2179 (Dezimal), oder 883 (Hex). Das bilden der Checksumme über die "8 Least Significant Bits (LSB)" bringt bei mir nicht das gewünschte Ergebnis. Laut einem Beispiel-Datensatz in der Schnittstellenbeschreibung ist die Checksumme dieses Zeichenkette 55.

Nachlesen der Begriffe LSB und MSB hat mich die letzten Tage leider auch nicht weiter gebracht. Hat wer eine Idee oder einen Lösungsansatz?

lg,
Andi

alzaimar 16. Feb 2009 06:46

Re: Checksumme in einem Übertragungsprotokoll bilden (LSB)
 
Dein Algorithmus ist falsch und verwendet nicht alle Zeichen des Frames. Zeig mal den Code.

bug0815 16. Feb 2009 06:59

Re: Checksumme in einem Übertragungsprotokoll bilden (LSB)
 
Die Aufsummierung der Zeichen erledige ich zum Testen mit folgendem Code:

Aufruf mit den betroffenen Zeichen aus dem Beispiel:
Delphi-Quellcode:
Label1.Caption := CreateCheckSum('01/00044/O/01/01720123445/2323//3/54657374/');
Funktion:
Delphi-Quellcode:
function TForm1.CreateCheckSum(InStr: String): String;
var rCount,
    Sum  : Integer;
begin
  Sum := 0;
  for rCount := 1 to Length(InStr) do
  begin
    Sum := Sum + Ord(InStr[rCount]);
  end;
  Result := IntToStr(Sum) + ' (' + IntToHex(Sum, 2) + ')';
end;
Der ganze Frame ist:
<stx>01/00044/O/01/01720123445/2323//3/54657374/<chksum><etx>

lg,
Andi

alzaimar 16. Feb 2009 07:25

Re: Checksumme in einem Übertragungsprotokoll bilden (LSB)
 
Gut, dann korrigiere ich mich: Der Algorithmus ist korrekt und summiert alle Zeichen. Wenn Du zu 100% den korrekten Frame aus der Beschreibung abgetippt hast (Mich hat. z.B. das 'O' (Oh) stutzig gemacht), dann kontaktiere doch mal den Hersteller...

Oder versuche Folgendes:
Schicke nacheinander den Frame mit allen möglichen Prüfsummen.
Bei genau Einer wird die Gegenstelle positiv reagieren.
Wiederhole dies mit diversen Frames.
Vergleiche deine und die 'korrekte' Prüfsumme.

WS1976 16. Feb 2009 07:38

Re: Checksumme in einem Übertragungsprotokoll bilden (LSB)
 
Hallo,
wir verwenden folgenden Algorithmus:

Delphi-Quellcode:
// Tabelle nach CCITT
Crc16Tab : Array[0..255] of Word = (
$0000, $1021, $2042, $3063, $4084, $50a5, $60c6, $70e7,
$8108, $9129, $a14a, $b16b, $c18c, $d1ad, $e1ce, $f1ef,
$1231, $0210, $3273, $2252, $52b5, $4294, $72f7, $62d6,
$9339, $8318, $b37b, $a35a, $d3bd, $c39c, $f3ff, $e3de,
$2462, $3443, $0420, $1401, $64e6, $74c7, $44a4, $5485,
$a56a, $b54b, $8528, $9509, $e5ee, $f5cf, $c5ac, $d58d,
$3653, $2672, $1611, $0630, $76d7, $66f6, $5695, $46b4,
$b75b, $a77a, $9719, $8738, $f7df, $e7fe, $d79d, $c7bc,
$48c4, $58e5, $6886, $78a7, $0840, $1861, $2802, $3823,
$c9cc, $d9ed, $e98e, $f9af, $8948, $9969, $a90a, $b92b,
$5af5, $4ad4, $7ab7, $6a96, $1a71, $0a50, $3a33, $2a12,
$dbfd, $cbdc, $fbbf, $eb9e, $9b79, $8b58, $bb3b, $ab1a,
$6ca6, $7c87, $4ce4, $5cc5, $2c22, $3c03, $0c60, $1c41,
$edae, $fd8f, $cdec, $ddcd, $ad2a, $bd0b, $8d68, $9d49,
$7e97, $6eb6, $5ed5, $4ef4, $3e13, $2e32, $1e51, $0e70,
$ff9f, $efbe, $dfdd, $cffc, $bf1b, $af3a, $9f59, $8f78,
$9188, $81a9, $b1ca, $a1eb, $d10c, $c12d, $f14e, $e16f,
$1080, $00a1, $30c2, $20e3, $5004, $4025, $7046, $6067,
$83b9, $9398, $a3fb, $b3da, $c33d, $d31c, $e37f, $f35e,
$02b1, $1290, $22f3, $32d2, $4235, $5214, $6277, $7256,
$b5ea, $a5cb, $95a8, $8589, $f56e, $e54f, $d52c, $c50d,
$34e2, $24c3, $14a0, $0481, $7466, $6447, $5424, $4405,
$a7db, $b7fa, $8799, $97b8, $e75f, $f77e, $c71d, $d73c,
$26d3, $36f2, $0691, $16b0, $6657, $7676, $4615, $5634,
$d94c, $c96d, $f90e, $e92f, $99c8, $89e9, $b98a, $a9ab,
$5844, $4865, $7806, $6827, $18c0, $08e1, $3882, $28a3,
$cb7d, $db5c, $eb3f, $fb1e, $8bf9, $9bd8, $abbb, $bb9a,
$4a75, $5a54, $6a37, $7a16, $0af1, $1ad0, $2ab3, $3a92,
$fd2e, $ed0f, $dd6c, $cd4d, $bdaa, $ad8b, $9de8, $8dc9,
$7c26, $6c07, $5c64, $4c45, $3ca2, $2c83, $1ce0, $0cc1,
$ef1f, $ff3e, $cf5d, $df7c, $af9b, $bfba, $8fd9, $9ff8,
$6e17, $7e36, $4e55, $5e74, $2e93, $3eb2, $0ed1, $1ef0
);

//generiere 16Bit CRC nach CCITT
Function GenerateCRC16(Var s1:String):Word;
Var crc16:Word; i:Integer;
Begin
  crc16 := $1D0F;
  For i := 1 to Length(s1) do Begin
    Crc16 := Crc16Tab[((Crc16 shr 8 ) xor Ord(s1[i])) and $ff] xor ((Crc16 shl 8) and $FFFF);
  End;
  Result := crc16;
End;
Grüsse
Rainer

PS: Bin zu faul deinen nachzuvollziehen, deshalb sende ich dir meinen!
Das Teil stammt von einem Kollegen. Details bitte Wikipedia entnehmen.

bug0815 16. Feb 2009 09:05

Re: Checksumme in einem Übertragungsprotokoll bilden (LSB)
 
Erst mal Danke für die Hinweise,

leider komme ich mit keinem Ansatz auf das angestrebte Ergebnis von 55.

Wenn ich die Schnittstellenbeschreibung richtig verstanden habe, sollen erst mal alle Bytes aufsummiert werden. So weit, so gut. Vom Ergebis soll man die 8 LSB als Checksumme nehmen. Und hier ist auch mein Verständnisproblem. Wikipedia & Co haben mir nicht wirklich weitergeholfen, ich hab mich irgendwie festgefahren.

Kann mir wer plausibel erklären, oder einen hilfreichen Link posten, was die 8 LSB meiner Summe 2179 (Dezimal), oder 0883 (Hex) sind. Wenn ich das mal Verstanden habe, kann ich etwas leichter nach weiteren Lösungsansätzen suchen.

lg,
Andi

GPRSNerd 16. Feb 2009 09:31

Re: Checksumme in einem Übertragungsprotokoll bilden (LSB)
 
Die 8 LSBs sind die Bits 0-7 der Binärdarstellung deiner Zahl.
Wenn du 2179 AND $FF berechnest, sollte 131=$83 rauskommen.

Wie auch immer, das ist nicht gleich der gesuchten 55.

Memo 16. Feb 2009 09:55

Re: Checksumme in einem Übertragungsprotokoll bilden (LSB)
 
Delphi-Quellcode:
function CheckData(s: string): string;
var
  i: integer;
  SumAscii: integer;
  L: integer;
begin
    SumAscii := 0;
    for i := 1 to Length(s) - 3 do
      SumAscii := SumAscii + Ord(s[i]);

    L := (SumAscii shr 8) and $00FF;
    Result := IntToHex(L,1);
end;



procedure TForm1.btn1Click(Sender: TObject);
begin
  lbl1.Caption:= CheckData('01/00044/O/01/01720123445/2323//3/54657374/')
end;

GPRSNerd 16. Feb 2009 10:09

Re: Checksumme in einem Übertragungsprotokoll bilden (LSB)
 
@Memo:

Sorry, aber der Algorithmus hat zwei Fehler:

1. Die for-Schleife muss bis Length(s) laufen
2. Was soll das ShiftRechts? Damit entsorgst du die 8 LSBs.

Delphi-Quellcode:
function CheckData(s: string): string;
var
  i: integer;
  SumAscii: integer;
  L: integer;
begin
    SumAscii := 0;
    for i := 1 to Length(s) do
      SumAscii := SumAscii + Ord(s[i]);
    //ShowMessage(IntToHex(SumAscii,8));
    L := SumAscii and $FF;
    Result := IntToHex(L,1);
end;

procedure TForm2.btn1Click(Sender: TObject);
begin
  ShowMessage(CheckData('01/00044/O/01/01720123445/2323//3/54657374/'));
end;
Mit diesem Code kommt auch wieder $883 und als Checkusmme $83 raus.

gammatester 16. Feb 2009 10:33

Re: Checksumme in einem Übertragungsprotokoll bilden (LSB)
 
Gibt es Schnittstellenbeschreibung und Beispiel online?

Gammatester

Reinhard Kern 16. Feb 2009 10:34

Re: Checksumme in einem Übertragungsprotokoll bilden (LSB)
 
Zitat:

Zitat von bug0815
...
Kann mir wer plausibel erklären, oder einen hilfreichen Link posten, was die 8 LSB meiner Summe 2179 (Dezimal), oder 0883 (Hex) sind. Wenn ich das mal Verstanden habe, kann ich etwas leichter nach weiteren Lösungsansätzen suchen.

Hallo,

es ist viel einfacher als du denkst: in Hex-Darstellung sind das die letzten beiden Digits, also von $883 wird nur $83 verwendet. Deshalb brauchst du beim Summieren die oberen Bits und Bytes garnicht mitrechnen, du kannst immer gleich nur das unterste Byte weiterverwenden:

Delphi-Quellcode:
function TForm1.CreateCheckSum(InStr: String): String;
var rCount,
    Sum  : Integer;
begin
  Sum := 0;
  for rCount := 1 to Length(InStr) do
  begin
    Sum := (Sum + Ord(InStr[rCount])) and $FF;
   { oder Sum := (Sum + Ord(InStr[rCount])) Mod 256; }
  end;
  Result := IntToStr(Sum) + ' (' + IntToHex(Sum, 2) + ')';
end;
Dann brauchst du dir keine Gedanken darüber machen, wie gross die Summe werden kann.

WS1976: was soll er denn mit einem CCITT -Algorithmus, wenn das Gerät eine einfache Checksumme verwendet? Schreibst du die Geräte-Firmware für ihn um?

Gruss Reinhard

PS: wenn ich meine Geräte dokumentiere, rechne ich auch immer reale Prüfsummen aus, aber das ist mühsam; vielleicht hat sich der Autor einfach gedacht, 55 ist doch eine schöne Zahl, ohne das in Bezug zum Beispielstring zu setzen. Oder er hat sich einfach verrechnet.

HaJo 16. Feb 2009 10:51

Re: Checksumme in einem Übertragungsprotokoll bilden (LSB)
 
Ach herje, was für ein sch.. Thema,
da kann ich auch nur zur allgemeinen Verunsicherungen beitragen.

Wie Reinhard schon schrieb:
Zitat:

PS: wenn ich meine Geräte dokumentiere, rechne ich auch immer reale Prüfsummen aus, aber das ist mühsam; vielleicht hat sich der Autor einfach gedacht, 55 ist doch eine schöne Zahl, ohne das in Bezug zum Beispielstring zu setzen. Oder er hat sich einfach verrechnet.
Bei der von mir gewarteten DEZ9000 muß ich an den auszuwertenden String ein ETX anhängen, damit die Prüfsumme mit der des Gerätes übereinstimmt. Obwohl es laut Beschreibung nicht sein darf!
Zudem kann es auch von der entsprechenden Firmware-Version abhängen.

Da ist fast alles Möglich. Genauso gut kann es auch immer die 55 sein! Ich kenne Beispiele, da wurde die Firmware und die Geräteeigene Prüfsumme von Lehrlingen implementiert und so ausgeliefert. Wohl ohne jegliche Kontrolle...

Da hilft nur beim Hersteller fragen, fragen fragen.

Gruß
Jochen

bug0815 16. Feb 2009 10:59

Re: Checksumme in einem Übertragungsprotokoll bilden (LSB)
 
Juhu, das Thema entwickelt Eigendynamic^^

Hier mal der Link zur kompletten Schnittstellenbeschreibung:
http://www.vodafone.de/downloadarea/EmiSpec_43c.pdf

Auf Seite 11 ist die Berechnung der Checksumme beschrieben. Beispielframes gibt es in der Beschreibung auch in ausreichender Anzahl.

lg,
Andi

gammatester 16. Feb 2009 11:23

Re: Checksumme in einem Übertragungsprotokoll bilden (LSB)
 
Das Beispiel aus dem pdf widerspricht dem Protokoll:
Zitat:

Of a call input operation, the alphanumeric message is: ´Test´: stx01/00044/O/01/01720123445/2323//3/54657374/55etx
Es sollten 44 Zeichen incl. Checksum sein, es sind aber 45. Wenn man aus '//' vor der 3 ein '/' macht, kommt man auf CS = 54; noch nicht ganz richtig, aber näher :)

Gammatester

bug0815 16. Feb 2009 11:38

Re: Checksumme in einem Übertragungsprotokoll bilden (LSB)
 
Hmmm, stimmt das mit der Länge ist eigenartig. Die beiden // sind aber richtig. An der Stelle wird ein nicht genutzer Parameter übergeben. Siehe Seite 19 4.4.1, N.A. Not Applied (but present)

Ich bin gerade dabei, mal mit ein paar anderen Beispielframes zu testen. Über weitere Anregungen würde ich mich freuen.

lg,
Andi

bug0815 16. Feb 2009 12:52

Re: Checksumme in einem Übertragungsprotokoll bilden (LSB)
 
Hallo zusammen,

danke an alle die sich beteiligt haben. Die Lösung des Problems ist ganz einfach. Ich war einfach nur der Pechvogel, der sich ein fehlerhaftes Frame-Beispiel für seine Versuche aus der Beschreibung gepickt hat. Mit den anderen Frames geht es einwandfrei.

lg,
Andi

WS1976 17. Feb 2009 06:34

Re: Checksumme in einem Übertragungsprotokoll bilden (LSB)
 
Hallo bug0815,

bitte probiers doch mal, obwohl da steht "nur Summe bilden" mit meinem Algorithmus.
Ist ja ein Versuch wert.

OK erledigt, vergiss es!

Grüsse
Rainer


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