代码之家  ›  专栏  ›  技术社区  ›  Remko

提高Crc16计算速度

  •  2
  • Remko  · 技术社区  · 14 年前

    因此,我的问题是如何改进我当前的实现(使其更快),我在google上搜索并查看了一些实现表查找的示例,但我的问题是我不知道如何修改它们以包含多项式(可能我的数学失败了)。

    { based on http://miscel.dk/MiscEl/CRCcalculations.html }
    function Crc16(const Buffer: PByte; const BufSize: Int64;
      const Polynom: WORD=$1021; const Seed: WORD=0): Word;
    var
      i,j: Integer;
    begin
      Result := Seed;
    
      for i:=0 to BufSize-1 do
      begin
        Result := Result xor (Buffer[i] shl 8);
    
        for j:=0 to 7 do begin
          if (Result and $8000) <> 0 then
            Result := (Result shl 1) xor Polynom
          else Result := Result shl 1;
        end;
      end;
    
      Result := Result and $FFFF;
    end;
    
    4 回复  |  直到 14 年前
        1
  •  2
  •   Andrej KirejeÅ­    14 年前

    从中查找CRC例程jclMath.pas文件绝地密码库单位。它使用CRC查找表。

    http://jcl.svn.sourceforge.net/viewvc/jcl/trunk/jcl/source/common/

        3
  •  2
  •   Rob Kennedy    14 年前

    你的 Result Word ,这意味着在进入内部循环时可能有64k个值。计算循环可以生成的64k个可能结果,并将它们存储在一个数组中。然后,不必为输入缓冲区的每个字节循环8次,只需在数组中查找校验和的下一个值。像这样:

    function Crc16(const Buffer: PByte; const BufSize: Int64;
      const Polynom: Word = $1021; const Seed: Word = 0): Word;
    {$J+}
    const
      Results: array of Word = nil;
      OldPolynom: Word = 0;
    {$J-}
    var
      i, j: Integer;
    begin
      if (Polynom <> OldPolynom) or not Assigned(Results) then begin
        SetLength(Results, 65535);
        for i := 0 to Pred(Length(Results)) do begin
          Results[i] := i;
          for j := 0 to 7 do
            if (Results[i] and $8000) <> 0 then
              Results[i] := (Results[i] shl 1) xor Polynom
            else
              Results[i] := Results[i] shl 1;
        end;
        OldPolynom := Polynom;
      end;
    
      Result := Seed;
      for i := 0 to Pred(BufSize) do
        Result := Results[Result xor (Buffer[i] shl 8)];
    end;
    

    该代码随时重新计算查找表 Polynom

    如果 总是 如果是1021美元,那就不用为它设置参数了。提前计算所有64k值并将它们硬编码到一个大数组中,这样您的整个函数就减少到上面我的函数的最后三行。

        4
  •  1
  •   Codebeat    13 年前

    function crc16( s : string; bSumPos : Boolean = FALSE ) : Word;
    var
     L, crc, sum, i, x, j : Word;
    
    begin
      Result:=0;
      L:=length(s);
      if( L > 0 ) then
       begin
        crc:=$FFFF;
        sum:=length(s);
        for i:=1 to L do
        begin
                j:=ord(s[i]); 
                sum:=sum+((i) * j);
                x:=((crc shr 8) xor j) and $FF;
                x:=x xor (x shr 4);
                crc:=((crc shl 8) xor (x shl 12) xor (x shl 5) xor x) and $FFFF;
        end;
        Result:=crc+(Byte(bSumPos) * sum);
       end;
    end;
    

    function uniqueId( s : string ) : Word;
    begin
     Result:=crc16( s, TRUE );
    end;
    

    干杯, 埃尔文·汉特杰斯