Delphi: Loop through bytes in record to calculate a simple checksum
If you have a record in Delphi or Pascal that contains multiple bytes or arrays of bytes, and you need to loop over the bytes inside to create a simple checksum by adding each byte to the checksum, you can do this in a loop without having to go over each element inside the record individually.
Here's a simple way to achieve this using pointers and the SizeOf function:
var
sum: Byte;
ptr: PByte;
i: Integer;
begin
sum := 0;
ptr := PByte(@rdmPacket);
for i := 0 to SizeOf(TRdmPacket) - 1 do
begin
sum := sum xor ptr^;
Inc(ptr);
end;
end;
In this code, we first initialize a variable sum to 0, which will hold the checksum. We then declare a pointer ptr of type PByte and assign it the address of the rdmPacket variable using the @ symbol.
We then loop through the record using a for loop, where the loop counter i goes from 0 to SizeOf(TRdmPacket) - 1. In each iteration, we perform an XOR operation between the current value of sum and the byte pointed to by ptr, and store the result back in sum. We then increment the pointer using the Inc function to point to the next byte in the record.
This method works correctly because all fields in the TRdmPacket record are bytes or arrays of bytes, and they are not aligned. However, it's worth noting that the alignment of fields in a record can affect the internal layout of the record, so you should be careful when using this method with other types of records. You can read more about the Packed attribute and the $Align directive in the Delphi documentation.
Alternatively, you can use the Absolute directive to achieve the same result:
type
TRdmPacket = record
sc: byte;
subSc: byte;
msgLength: byte;
destUID: array[0..5] of byte;
srcUID: array[0..5] of byte;
transNum: byte;
portID: byte;
msgCount: byte;
subDevice: array[0..1] of byte;
cc: byte;
pid: array[0..1] of byte;
pdl: byte;
end;
Function GetPackChecksum( pack:TRdmPacket):Integer;
var
BArray:Array [0..SizeOf(TRdmPacket) - 1] of Byte absolute pack;
i:Integer;
begin
Result := 0;
for I := Low (BArray)to High(BArray) do
begin
Result := Result + BArray[i];
end;
end;
procedure TForm2.Button1Click(Sender: TObject);
var
pack:TRdmPacket;
begin
ZeroMemory(@pack,SizeOf(Pack));
pack.sc := 100;
pack.destUID[1] := 123;
Showmessage(IntToStr(GetPackChecksum(pack)));
end;
In this code, we declare an array BArray of bytes using the Absolute directive, which allows us to access the bytes of the pack record directly. We then loop through the array using a for loop, adding each byte to the Result variable, which holds the checksum.
Both of these methods allow you to loop through the bytes of a record in Delphi or Pascal and calculate a simple checksum without having to access each field individually.
Описание 'Context': В данном контексте рассматривается задача прохода по байтам в записи (record) на языке Delphi или Паскаль для расчета простого контрольной суммы (checksum) путем сложения каждого байта с суммой. Для этого можно использовать цикл (loop)
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.