Ваша переменная Result
является Word
, что означает, что существует 64 000 возможных значений, которые она может иметь при входе во внутренний цикл. Рассчитайте 64 тыс. Возможных результатов, которые цикл может генерировать, и сохраните их в массиве. Затем вместо восьми циклов для каждого байта входного буфера просто ищите следующее значение контрольной суммы в массиве. Примерно так:
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
изменения. Если этот параметр варьируется среди набора значений, рассмотрите возможность кэширования создаваемых для них таблиц поиска, чтобы не тратить время на повторный расчет одних и тех же таблиц.
Если Polynom
будет , всегда будет $ 1021, то даже не беспокойтесь о параметре для него. Вычислите все значения 64 КБ заранее и жестко закодируйте их в большом массиве, чтобы вся ваша функция была сокращена до последних трех строк моей функции выше.