Як підрахувати контрольну суму файлу
А можна детальніше?
по модулю 256 = x mod 256
Соррі, я не розумію як це зробити, можна код?
За модулю 256 в даному контесті означає ігнорувати перенесення, можна звичайно і так, але ефективніше просто використовувати байт і блокровать помилку переповнення. Хоча сама операція не займає багато часу, але вона може виконуватися над великим масивом даних
А можна запитати що таке алгоритм CRC?
Можна, це код зменшує помилку (в перекладі), заснований на більш складному алгоритмі, ніж просто підсумовування байтів, сущест велика кількість таких алгоритмом, ряд з них визнаний стандартними.
Може підійдемо до суті, що ти хочеш зробити, навіщо, а то як то беспрдметно.
Але своє питання ти вже давно отримав відповідь, підсумовують всі байти по модулю 256, по закінченню отримаєш контрольну суму.
Алгоритм CRC це метод обчислення сигнатури (контрольної суми) даних, що дозволяє з відомою ймовірністю визначити достовірність даних при їх можливих викривлення в процесі передачі, зберігання.
Мені потрібно зробити наступне: при зміні коду моєї програми, будь то пряме редагування коду або написання програми-патча, перед запуском моєї програми йшла перевірка на зміну коду і якщо це сталося просто переривати програму.
P.S. якщо не хочеться відповідати докладніше, то я сам спробую знайти де-небудь відповідь.
Eugene_post (23.10.02 21:47)
Захист справа тонка, врахуй що будуть викусивать перевірку не розбираючись як і що ти вважаєш. Але в будь-якому випадку CRC ефективніше ніж CS
const
CrcPolynominal = $ 04C11DB7;
// *******************************
// * Calculate Crc32 with buffer *
// *******************************
function BufToCrc (const Buf; Count: Integer). Longint;
var
I. Integer;
begin
Result: = $ FFFFFFFF;
for I: = 0 to Count - 1 do begin
Result: = Crc32 (Byte (TByteArray (Buf) [I]), Result);
end;
end;
// *******************************
// * Calculate Crc32 with string *
// *******************************
function StrToCrc (Value: string). Longint;
var
I. Integer;
begin
Result: = $ FFFFFFFF;
for I: = 1 to Length (Value) do begin
Result: = Crc32 (Byte (Value [I]), Result);
end;
end;
Для електронників (ассемблерщіков) - можна уявити собі зсувний регістр з відводами від необхідних розрядів (при ступенях Х) і все відводи і вхідні однобітний послідовність складаються з "модулю 2" і вводяться побитно в регістр.
Після проходження всього числа в регістрі і виявиться сигнатура (CRC).
Цей метод екстраполюється і на многобітную обробку.
Для прискорення обчислення реально використовуються табличні методи.
До речі, ті ж Непріводімие поліноми використовуються і для генерації псевдовипадкових чисел.
> Eugene_post
Ще один варіант реалізації
const
CrcSeed = $ ffffffff;
function Crc32 (Buffer. Pointer; const BufLen. DWord; Crc. DWord). DWORD; assembler;
asm
push edi
mov edi, eax
mov eax, ecx
mov ecx, edx
and ecx, ecx
jz @Exit
and edi, edi
jz @Exit
@Start:
xor edx, edx
mov dl, al
shr eax, 8
xor dl, [edi]
xor eax, dword ptr [4 * edx + crctable32]
inc edi
loop @Start
@Exit:
pop edi
end;
function CrcStream (Stream. TStream). DWORD;
var
P. Pointer;
C. LongInt;
begin
Result: = CrcSeed;
GetMem (P, 8192);
try
Stream.Position: = 0;
while Stream.Position
Result: = Crc32 (P, C, Result)
end
finally
FreeMem (P, 8192)
end;
Result: = Result xor CrcSeed
end;
function CrcFile (const FileName. string). DWORD;
var
Stream. TFileStream;
begin
Stream: = TFileStream.Create (FileName, fmOpenRead + fmShareDenyNone);
try
Result: = CrcStream (Stream)
finally
Stream.Free
end
end;
Варіант з таблицею краще повністю перевести на Паскаль, алгоритмічний так просто не переведеш
Так, це табличний метод до породжує поліномом
FUNCTION UpdC32 (octet: BYTE; crc: LONGINT). LONGINT;
BEGIN
UpdC32: = crctabду32 [BYTE (crc XOR LONGINT (octet))] XOR ((crc SHR 8) AND $ 00FFFFFF)
END;
const
CRC32_POLYNOMIAL = $ EDB88320;
var
Ccitt32Table. array [0..255] of longint;
function crc32 (crc. longint; const c. byte). longint;
begin
crc32: = (((crc shr 8) and $ 00FFFFFF) xor (Ccitt32Table [(crc xor c) and $ FF]));
end;
procedure BuildCRCTable;
var
i, j, value. DWORD;
begin
for i: = 0 to 255 do
begin
value: = i;
for j: = 8 downto 1 do
begin
if ((value and 1) <> 0) then
value: = (value shr 1) xor CRC32_POLYNOMIAL
else
value: = value shr 1;
end;
Ccitt32Table [i]: = value;
end
end;
Це теж табличний метод, тільки таблиця обчислюється, а не зберігатися.
ROL AL, 1
RCL EDX, 1
JNC @ 2
Тут використовується прапор перенесення, а Паскалі до нього немає доступу. Але все залежить від цілей, мені єдино не подобається, так це використання ассемблерних команд, які не переносимість наприклад на технологію .NET