Newsgroup: it.comp.lang.delphi
Titolo: Traduzione Checksum Fletcher





Riporto il listato in C da me tradotto in Delphi, 
se notate errori vi ringrazio nel segnalarmeli.


si consideri che in caso di len dispari l'ultimo 
word e' costituito da Word=(0,UltimoByte)


const uint16_t *data;  /* Pointer to the data to be summed */
       size_t len;      /* Length in 16-bit words */
       uint32_t sum1 = 0xffff, sum2 = 0xffff;

       while (len) {
               unsigned tlen = len > 360 ? 360 : len;
               len -= tlen;
               do {
                       sum1 += *data++;
                       sum2 += sum1;
               } while (--tlen);
               sum1 = (sum1 & 0xffff) + (sum1 >> 16);
               sum2 = (sum2 & 0xffff) + (sum2 >> 16);
       }
       /* Second reduction step to reduce sums to 16 bits */
       sum1 = (sum1 & 0xffff) + (sum1 >> 16);
       sum2 = (sum2 & 0xffff) + (sum2 >> 16);
       return sum2 << 16 | sum1;
Traduzione in Delphi:
function TUdpCmd.CheckSum(Buff: TMemoryStream): LongWord;
var Len, TLen, Sum1, Sum2: LongWord; Data: Word;
begin
Buff.Position:=0;
Len:=Buff.Size div 2;
if Buff.Size mod 2 =1 then Inc(Len);
Sum1:=$FFFF; Sum2:=$FFFF;
//
While Len>0 do
  begin
  if Len>360 then
    TLen:=360
  else
    TLen:=Len;
  Len:=Len-TLen;
  Repeat
    Data:=0; // Nel caso di Len dispari!
    n:=Buff.Read(Data,2);
    Sum1:=Sum1+Data;
    Sum2:=Sum2+Sum1;
    Dec(TLen);
  Until TLen=0;
  Sum1:=(Sum1 And $FFFF)+Sum1 shr 16;
  Sum2:=(Sum2 And $FFFF)+Sum2 shr 16;
  end;
//
Sum1:=(Sum1 And $FFFF)+Sum1 shr 16;
Sum2:=(Sum2 And $FFFF)+Sum2 shr 16;
Result:=(Sum2 shl 16) Or Sum1;
end;
Giorgio
 



 ringrazio nel segnalarmeli.
Il seguente dovrebbe essere corretto, ma non ho testato la congruenza dei
risultati confrontandoli con altri calcolatori:
type
  TFletcherChecksum = class
  public
    class function Get(AStream: TStream): Word;
  end;
{ TFletcherChecksum }
class function TFletcherChecksum.Get(AStream: TStream): Word;
var
  Len, TLen: Cardinal;
  Sum1, Sum2: Cardinal;
  Data: Word;
begin
  Len := AStream.Size div 2;
  if (AStream.Size mod 2) <> 0 then 
    Inc(Len);
  Sum1 := $FFFF;
  Sum2 := $FFFF;
  while (Len>0) do
  begin
    if Len>360 then
      TLen := 360
    else
      TLen := Len;
    Dec(Len, TLen);
    repeat
      Data := 0;
      AStream.Read(Data, 2);
      Inc(Sum1, Data);
      Inc(Sum2, Sum1);
      Dec(TLen);
    until TLen=0;
    Sum1 := (Sum1 and $FFFF) + (Sum1 shr 16);
    Sum2 := (Sum2 and $FFFF) + (Sum2 shr 16);
  end;
  Sum1 := (Sum1 and $FFFF) + (Sum1 shr 16);
  Sum2 := (Sum2 and $FFFF) + (Sum2 shr 16);
  Result := Sum2 shl 16 or Sum1;
end;
type
  TFletcherChecksumTester = class
  public
    class procedure Test;
  end;
{ TFletcherChecksumTester }
class procedure TFletcherChecksumTester.Test;
const
  Buf1: String = 'abc';
  Buf2: String = 'ab';
begin
  ShowMessageFmt('checksum for "%s" is %d',
    [Buf1, TFletcherChecksum.Get(TStringStream.Create(Buf1))]);
  ShowMessageFmt('checksum for "%s" is %d',
    [Buf2, TFletcherChecksum.Get(TStringStream.Create(Buf2))]);
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
  TFletcherChecksumTester.Test;
end;
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it

>    class function Get(AStream: TStream): Word;
Dal calcolo che esegue su Result penso che sia necessaria una var. Cardinal 
(unsigned 32bit).
Giorgio 

 (unsigned 32bit).
Effettivamente, anche se dalla teoria mi era sembrato di capire che il
checksum Fletcher fosse a 16 bit.
