Эта статья будет про режим /mode +x в Ирц.. И про то, как же его можно расшифровать? Потому как всегда легче и приятней знать IP собеседника. Мало ли кто там - на другом конце провода?
Начнем! Для начала я взял и посмотрел исходники irсd (Rusnet). Для Каждой сети свой метод. Ну чтож - у нас народ пользуется Руснетом. про него и напишем..
Вот они:
Код:
if (!IsRusnetServices(sptr))
{ /*
** false data for usermode +x. After really long discussion
** it's been concluded to false last three octets of IP
** address and first two parts of hostname to provide
** the reasonable compromise between security and
** channels ban lists. Host.domain.tld is mapped to
** crc32(host.domain.tld).crc32(domain.tld).domain.tld
** and domain.tld to crc32(domain.tld).crc32(tld).domain.tld
** respectively --erra
**
** some modification there: eggdrop masking compatibility
** with the same hide availability
** Let's say crcsum() is crc32 of complete hostname. Then:
** a12.b34.sub.host.domain.tld -> crcsum().crc32(sub.host.domain.tld).host.domain.tld
** a12-b34.sub.host.domain.tld -> crcsum().crc32(sub.host.domain.tld).host.domain.tld
** comp.sub.host.domain.tld -> crcsum().crc32(sub.host.domain.tld).host.domain.tld
** a12.b34.host.domain.tld -> crcsum().crc32(b34.host.domain.tld).host.domain.tld
** a12-b34.host.domain.tld -> crcsum().crc32(crcsum()).host.domain.tld
** sub.host.domain.tld -> crcsum().crc32(crcsum()).host.domain.tld
** a12.b34.domain.tld -> crcsum().crc32(b34.domain.tld).domain.tld
** a12-b34.domain.tld -> crcsum().crc32(crcsum()).domain.tld
** host.domain.tld -> crcsum().crc32(crcsum()).domain.tld
** a12.dom2usr.tld -> crcsum().crc32(crcsum()).dom2usr.tld
** domain.tld -> crcsum().crc32(crcsum()).domain.tld
** domain. -> crcsum().crc32(domain.crcsum()).domain
**/
char *s = sptr->sockhost;
char *c = s + strlen(s);
int n = 0;
while (c > s)
{
c--;
if (*c == '.' && (++n) == 3) /* 4th dot reached */
break;
else if (*c <= '9' && *c >= '0')
break;
}
if (n) /* hostname second level or above... duh */
{
int len;
/* ignore digits in second-level domain part
when there are no minus signs --erra
*/
if (c > s && n == 1)
while (c > s && *c != '.') {
if (*c == '-') {
do c++;
while (*c != '.');
break;
}
c--;
}
else /* *c cannot reach \0 - see above */
while (*c != '.')
c++;
s = c;
while (s > sptr->sockhost && *(--s) != '.');
if (*s == '.') /* s is part for second crc32 */
s++;
if (s == sptr->sockhost) /* it needs crc32(crcsum()) */
s = user->host;
/* finished gathering data, let's rock */
strcpy(user->host, b64enc(gen_crc(sptr->sockhost)));
strcat(user->host, ".");
strcat(user->host, b64enc(gen_crc(s)));
len = strlen(user->host);
n = len + strlen© - HOSTLEN;
if (n > 0) /* overrun protection */
user->host[len - n] = '\0';
strcat(user->host, c);
}
else if (c == s) /* are there hosts w/o dots? Yes */
{
strcpy(user->host, sptr->sockhost);
#if 0 /* stupid masking, really */
strcat(user->host, ".");
strcpy(user->host, b64enc(gen_crc(user->host)));
strcat(user->host, ".");
strcat(user->host, b64enc(gen_crc(user->host)));
strcat(user->host, ".");
strcat(user->host, sptr->sockhost);
#endif
}
else /* IP address.. reverse search */
{
char *pfx;
s = strrchr(user->host, '.');
if (!s) {
ircstp->is_kill++;
sendto_one(cptr,
":%s KILL %s :%s (Bad hostmask)", ME, sptr->name, ME);
sptr->flags |= FLAGS_KILLED;
return exit_client(NULL, sptr, &me, "Bad hostmask");
}
*s = '\0';
DupString(pfx, b64enc(gen_crc(user->host)));
s = strchr(user->host, '.'); /* keep 1st octet */
if (!s) {
ircstp->is_kill++;
sendto_one(cptr,
":%s KILL %s :%s (Bad hostmask)", ME, sptr->name, ME);
sptr->flags |= FLAGS_KILLED;
return exit_client(NULL, sptr, &me, "Bad hostmask");
}
strcpy(++s, b64enc(gen_crc(sptr->sockhost)));
strcat(user->host, ".");
strcat(user->host, pfx);
strcat(user->host, ".in-addr");
MyFree(pfx);
}
}
С++! Я его, конечно же, не знаю, но все равно это дает нам стимул копать дальше! то есть из этих исходников вполне понятно, что все шифруется все Алгоритмом crc32..
crc(Cyclic Redundancy Code ) - аббревиатура расшифровывается как циклический избыточный код. Этот алгоритм полностью обратим для коротких паролей.. (до 4-х символов) и также частично обратим для всех остальных.
Было доказано, что для нахождения коллизии (пароля, контрольная сумма которого будет такая же, как и у оригинального) потребуется не более 7 печатных символов. А для подбора пароля к хэшу потребуется не более минуты..
Из этого мы можем сделать вывод, что алгоритм Cyclic Redundancy Code является частично обратим, чем меньше знаков - тем легче мы можем его расшифровать, а если же как в хосте - то можно сбрутить очень быстро, так как хост шифруется частично в режиме +x! Конечно, можно пуститься в долгие рассуждения, но я постаралась найти брутеры и способы расшифровки crc32.
Чем же отличается сrс от сrс32?
Рассмотрим на примере "таблицы", виток каждого цикла составляет 1 байт:
"простой" алгоритм(т.е. однобитовый) прост. но так как он работает на битовом уровне, его трудно закодировать (даже в C), а эффективность его низка, так как полный цикл выполняется по биту. Для увеличения скорости работы нам необходимо найти способ заставить алгоритм работать с блоками, большими чем бит. Такими блоками могут быть
полубайты (4 бита), байты, (8 бит), слова (16 бит) и длинные слова (32 бита), и даже более длинные фрагменты, если мы сможем с ними работать. Полубайты не выровнены на границу байта, поэтому нам будет неудобно их использовать, и для увеличения скорости работы с таким алгоритмом нам нужно выравнивание по байтам - большинство алгоритмов работают именно с байтами. И именно по этой причине нам удобнее использовать алгоритм crc32, так как он выровнен по байтам.
так как я сама чуть тут не запуталась нарисую небольшой пример такой "таблицы"
Вот так примерно все это выглядит, поэтому преимущества crc32 налицо. Но давайте я всеже напишу про ирц.. так как это частично обратимый алгоритм - легче его будет брутить. Я добыла в нечестном бою исходники брутфорса на асме. Это если вдруг понадобится восстановить что-нибудь дболее существенное, чем IP:
Код:
;=====================================================================
format pe gui
include '%fasminc%\win32a.inc'
;=====================================================================
first = '0'
flast = 'z' +1
;=====================================================================
serial rb 1024
crc32_table dd 000000000h, 077073096h, 0EE0E612Ch, 0990951BAh, 0076DC419h, 0706AF48Fh, 0E963A535h, 09E6495A3h, 00EDB8832h, 079DCB8A4h
dd 0E0D5E91Eh, 097D2D988h, 009B64C2Bh, 07EB17CBDh, 0E7B82D07h, 090BF1D91h, 01DB71064h, 06AB020F2h, 0F3B97148h, 084BE41DEh
dd 01ADAD47Dh, 06DDDE4EBh, 0F4D4B551h, 083D385C7h, 0136C9856h, 0646BA8C0h, 0FD62F97Ah, 08A65C9ECh, 014015C4Fh, 063066CD9h
dd 0FA0F3D63h, 08D080DF5h, 03B6E20C8h, 04C69105Eh, 0D56041E4h, 0A2677172h, 03C03E4D1h, 04B04D447h, 0D20D85FDh, 0A50AB56Bh
dd 035B5A8FAh, 042B2986Ch, 0DBBBC9D6h, 0ACBCF940h, 032D86CE3h, 045DF5C75h, 0DCD60DCFh, 0ABD13D59h, 026D930ACh, 051DE003Ah
dd 0C8D75180h, 0BFD06116h, 021B4F4B5h, 056B3C423h, 0CFBA9599h, 0B8BDA50Fh, 02802B89Eh, 05F058808h, 0C60CD9B2h, 0B10BE924h
dd 02F6F7C87h, 058684C11h, 0C1611DABh, 0B6662D3Dh, 076DC4190h, 001DB7106h, 098D220BCh, 0EFD5102Ah, 071B18589h, 006B6B51Fh
dd 09FBFE4A5h, 0E8B8D433h, 07807C9A2h, 00F00F934h, 09609A88Eh, 0E10E9818h, 07F6A0DBBh, 0086D3D2Dh, 091646C97h, 0E6635C01h
dd 06B6B51F4h, 01C6C6162h, 0856530D8h, 0F262004Eh, 06C0695EDh, 01B01A57Bh, 08208F4C1h, 0F50FC457h, 065B0D9C6h, 012B7E950h
dd 08BBEB8EAh, 0FCB9887Ch, 062DD1DDFh, 015DA2D49h, 08CD37CF3h, 0FBD44C65h, 04DB26158h, 03AB551CEh, 0A3BC0074h, 0D4BB30E2h
dd 04ADFA541h, 03DD895D7h, 0A4D1C46Dh, 0D3D6F4FBh, 04369E96Ah, 0346ED9FCh, 0AD678846h, 0DA60B8D0h, 044042D73h, 033031DE5h
dd 0AA0A4C5Fh, 0DD0D7CC9h, 05005713Ch, 0270241AAh, 0BE0B1010h, 0C90C2086h, 05768B525h, 0206F85B3h, 0B966D409h, 0CE61E49Fh
dd 05EDEF90Eh, 029D9C998h, 0B0D09822h, 0C7D7A8B4h, 059B33D17h, 02EB40D81h, 0B7BD5C3Bh, 0C0BA6CADh, 0EDB88320h, 09ABFB3B6h
dd 003B6E20Ch, 074B1D29Ah, 0EAD54739h, 09DD277AFh, 004DB2615h, 073DC1683h, 0E3630B12h, 094643B84h, 00D6D6A3Eh, 07A6A5AA8h
dd 0E40ECF0Bh, 09309FF9Dh, 00A00AE27h, 07D079EB1h, 0F00F9344h, 08708A3D2h, 01E01F268h, 06906C2FEh, 0F762575Dh, 0806567CBh
dd 0196C3671h, 06E6B06E7h, 0FED41B76h, 089D32BE0h, 010DA7A5Ah, 067DD4ACCh, 0F9B9DF6Fh, 08EBEEFF9h, 017B7BE43h, 060B08ED5h
dd 0D6D6A3E8h, 0A1D1937Eh, 038D8C2C4h, 04FDFF252h, 0D1BB67F1h, 0A6BC5767h, 03FB506DDh, 048B2364Bh, 0D80D2BDAh, 0AF0A1B4Ch
dd 036034AF6h, 041047A60h, 0DF60EFC3h, 0A867DF55h, 0316E8EEFh, 04669BE79h, 0CB61B38Ch, 0BC66831Ah, 0256FD2A0h, 05268E236h
dd 0CC0C7795h, 0BB0B4703h, 0220216B9h, 05505262Fh, 0C5BA3BBEh, 0B2BD0B28h, 02BB45A92h, 05CB36A04h, 0C2D7FFA7h, 0B5D0CF31h
dd 02CD99E8Bh, 05BDEAE1Dh, 09B64C2B0h, 0EC63F226h, 0756AA39Ch, 0026D930Ah, 09C0906A9h, 0EB0E363Fh, 072076785h, 005005713h
dd 095BF4A82h, 0E2B87A14h, 07BB12BAEh, 00CB61B38h, 092D28E9Bh, 0E5D5BE0Dh, 07CDCEFB7h, 00BDBDF21h, 086D3D2D4h, 0F1D4E242h
dd 068DDB3F8h, 01FDA836Eh, 081BE16CDh, 0F6B9265Bh, 06FB077E1h, 018B74777h, 088085AE6h, 0FF0F6A70h, 066063BCAh, 011010B5Ch
dd 08F659EFFh, 0F862AE69h, 0616BFFD3h, 0166CCF45h, 0A00AE278h, 0D70DD2EEh, 04E048354h, 03903B3C2h, 0A7672661h, 0D06016F7h
dd 04969474Dh, 03E6E77DBh, 0AED16A4Ah, 0D9D65ADCh, 040DF0B66h, 037D83BF0h, 0A9BCAE53h, 0DEBB9EC5h, 047B2CF7Fh, 030B5FFE9h
dd 0BDBDF21Ch, 0CABAC28Ah, 053B39330h, 024B4A3A6h, 0BAD03605h, 0CDD70693h, 054DE5729h, 023D967BFh, 0B3667A2Eh, 0C4614AB8h
dd 05D681B02h, 02A6F2B94h, 0B40BBE37h, 0C30C8EA1h, 05A05DF1Bh, 02D02EF8Dh
;=====================================================================
buffer rb 1024
result rb 1024
filename db 'bruteforce.log',0
complete db 'брутфорс окончен!',13,10
size = $-complete
align 1024
;=====================================================================
entry $
invoke CreateFile,filename,GENERIC_READ+GENERIC_WRITE,\
FILE_SHARE_READ+FILE_SHARE_WRITE,0,CREATE_ALWAYS,\
FILE_ATTRIBUTE_NORMAL,0
mov ebp,eax
mov eax,-4*8
@@: mov dword[serial+4*8+eax],first
mov dword[serial+4*8+eax+4],first
add eax,4*2
jnz @b
;=====================================================================
@0: mov ecx,dword[serial+4*0]
xor ecx,0xff
mov eax,dword[crc32_table+ecx*4]
xor eax,0x00ffffff
mov dword[buffer+4*0],eax
@1: mov ecx,dword[serial+4*1]
xor ecx,eax
shr eax,8
and ecx,0xff
xor eax,dword[crc32_table+ecx*4]
mov dword[buffer+4*1],eax
@2: mov ecx,dword[serial+4*2]
xor ecx,eax
shr eax,8
and ecx,0xff
xor eax,dword[crc32_table+ecx*4]
mov dword[buffer+4*2],eax
@3: mov ecx,dword[serial+4*3]
xor ecx,eax
shr eax,8
and ecx,0xff
xor eax,dword[crc32_table+ecx*4]
mov dword[buffer+4*3],eax
@4: mov ecx,dword[serial+4*4]
xor ecx,eax
shr eax,8
and ecx,0xff
xor eax,dword[crc32_table+ecx*4]
mov dword[buffer+4*4],eax
@5: mov ecx,dword[serial+4*5]
xor ecx,eax
shr eax,8
and ecx,0xff
xor eax,dword[crc32_table+ecx*4]
mov dword[buffer+4*5],eax
@6: mov ecx,dword[serial+4*6]
xor ecx,eax
shr eax,8
and ecx,0xff
xor eax,dword[crc32_table+ecx*4]
;=====================================================================
mov ebx,eax
shr eax,8
and ebx,0xff
xor eax,not 0x0a463daa ; not(CRC32(пароль инсталляции))
mov ecx,first
@@: mov edx,ebx
xor edx,ecx
cmp eax,dword[crc32_table+edx*4]
jz @found
inc ecx
cmp ecx,flast
jnz @b
;=====================================================================
@next: inc dword[serial+4*6]
cmp dword[serial+4*6],flast
mov eax,dword[buffer+4*5]
jnz @6
mov dword[serial+4*6],first
inc dword[serial+4*5]
cmp dword[serial+4*5],flast
mov eax,dword[buffer+4*4]
jnz @5
mov dword[serial+4*5],first
inc dword[serial+4*4]
cmp dword[serial+4*4],flast
mov eax,dword[buffer+4*3]
jnz @4
mov dword[serial+4*4],first
inc dword[serial+4*3]
cmp dword[serial+4*3],flast
mov eax,dword[buffer+4*2]
jnz @3
mov dword[serial+4*3],first
inc dword[serial+4*2]
cmp dword[serial+4*2],flast
mov eax,dword[buffer+4*1]
jnz @2
mov dword[serial+4*2],first
inc dword[serial+4*1]
cmp dword[serial+4*1],flast
mov eax,dword[buffer+4*0]
jnz @1
mov dword[serial+4*1],first
inc dword[serial+4*0]
cmp dword[serial+4*0],flast
jnz @0
jmp exit
;=====================================================================
@found: mov dword[serial+7*4],ecx
xor ecx,ecx
@@: mov eax,dword[serial+ecx*4]
mov byte[result+ecx],al
inc ecx
cmp ecx,8
jnz @b
mov word[result+ecx],0x0a0d
invoke WriteFile,ebp,result,10,esp,0
jmp @next
;=====================================================================
exit: invoke WriteFile,ebp,complete,size,esp,0
invoke CloseHandle,ebp
invoke ExitProcess,0
;=====================================================================
data import
library kernel32,'kernel32.dll'
include '%fasminc%\apia\kernel32.inc'
end data
;=====================================================================
Вот один из брутфорсов: находит всевозможные подходящие варианты на этот хэш (На наше счастье, их может быть несколько) скорость примерно 20 млн\сек! Этот Брутфорс написал LAZAR.
Вот еще один.. Вроде бы он побыстрее:
Еще один брутфорс
Все это добро компелируется фасмом! (flat assembler, fasm)
также есть и способы попроще для задач поменьше.. Раз уж статья написана с подачи Ирц, то грех не воспользоваться возможностями Ирц. В ирц есть отличный бот, который декодирует небольшие коды.
Имя бота - robo! Пробив его по хуису узнала, что живет он на каналах: #topki, #nothing, #moi-alizee, #freeware, #orsk, #boltalka, #mytest, #kashenizm, #, #myxo4ka, #fleur.
Команда такая: .dh (то, что зашифровано) - в ответ выдается сообщение нотисом. С ирц вроде разобрались..
Но есть еще полезные функции.. например связанные с архивами:
Архивы.. у вас никогда не было такого, что архив поврежден, или неожиданный конец архива? Вот у меня было - попробую и в этом разобраться..
Но вот выкладываю программку, которая восстанавливает архивы, точнее архиватор считает архив целым засчет изменения сrс32 хэша! Что самым прямым образом относится к теме:
RAR Repair Tool 3.1 (Shareware, но прога крякнутая ))
Ключевые возможности Rar Repair Tool:
- восстановление RAR и SFX архивов, созданных любой версией RAR;
- восстановление многотомных архивов;
- независимо от размера файлов (4 Gb и более);
- обработка нескольких архивов по списку;
- полная автоматизация процесса восстановления;
- поддержка Drag&Drop;
Сама прога тут
А теперь я попытаюсь обьяснить принцип работы:
архиватор - тоже вещь написанная людьми, и они повреждаются при транспартировке, неправильной упаковке. В crc32 коде могут быть ошибки при упаковке. Что приводит к повреждению архива.. С форматом RAR самой частой является ошибка с повреждением циклического кода.. То есть код при упаковке\распаковке не совпадает с исходным. Программы, которые восстанавливают архивы как-бы "восстанавливают" или "собирают" поврежденный код.. В итоге файлы можно извлечь.. Конечно без потерь может не обойтись, но это лучше чем ничего!
Ну вот примерно мы разобрались в коде crc32! поврежден архив? Восстановим.. нужен IP врага в ирц - а он гад шифруется? Получим... Но перед использованием надо знать примерный принцип работы для того, чтобы не быть юзерами, которые кликают по экрану мышкой в поисках ответа.. Удачи вам в ваших происках )
Изначально цель методик обнаружения ошибок была в том, чтобы дать возможность получателю сообщения, передаваемому по зашумленному каналу, определить, не было ли оно испорчено. Для этого отправитель формировал значение, именуемое контрольной суммой ("checksum" - КС), как функцию от сообщения и добавлял его к сообщению, получатель, используя ту же самую функцию, мог посчитать КС полученного сообщения и в случае равенства, считать сообщение безошибочно принятым. Самый первый алгоритм подсчета КС был очень прост: все байты сообщения суммировались (отсюда и пошло название <контрольная сумма>) по модулю степени двойки. Главное достоинство этого метода - простота, главный недостаток - ненадежность. Например, он не <замечает> перестановки байт местами.
Высокую степень безопасности данных обеспечивают алгоритмы контроля за достоверностью информации, использующие циклические избыточные коды (Cyclic Redundancy Code - CRC).
Использование CRC представляет собой сверхмощный метод обнаружения ошибок.
Авторам изученной мной литературы известны три различных теоретических аспекта расчета CRC, приводящих на практике к идентичным результатам:
матричная запись циклического кода,
метод деления на образующий полином над полем GF(2) и
способ образования CRC с помощью регистра сдвига с обратными связями.
Именно последний способ удобен с вычислительной точки зрения - особенно если разрядность компьютера равна (или кратна) длине сдвигового регистра.
Для простоты считайте CRC остатком от деления БОЛЬШОГО бинарного числа (передаваемых данных) на <магическое> число, в зависимости от разряда старшего бита этого числа выделяют CRC16 и CRC32.
Теория этого дела весьма обширна и хорошо описана в литературе, но думаю, большинство читателей этой статьи гораздо больше волнует её практическая реализация.
Алгоритм получения CRC32 такой:
1. CRC-32 инициализируется значением $FFFFFFFF
2. Для каждого байта "B" входной последовательности CRC-32 сдвигается вправо на 1 байт. Если байты CRC-32 были [C1,C2,C3,C4] (C1 - старший, C4 - младший), сдвиг дает [0,C1,C2,C3]. Младший байт C4 побитно складывается с B по модулю 2 (C4 xor B). Новым значением CRC-32 будет его сдвинутое значение, сложенное побитно по модулю 2 (xor) с 4-байтовой величиной из "магической" таблицы с использованием [B xor C4] в качестве индекса.
Было:
CRC-32 = [C1,C2,C3,C4] и получили очередной байт B.
Стало:
CRC-32 = [0,C1,C2,C3] xor Magic[B xor C4].
PAS: { CRC - LongWord, Magic - array[byte] of LongWord}
CRC := (CRC shr 8) xor Magic[B xor byte(CRC and $FF)];
3. Инвертировать все биты: CRC:= NOT CRC;
Код на паскале:-)
Const
Crc32Init = $FFFFFFFF;
Crc32Polynomial = $EDB88320;
Var
CRC32Table: array [Byte] of Cardinal;
function Crc32Next (Crc32Current: LongWord; const Data; Count: LongWord):
LongWord; register;
Asm file://EAX - CRC32Current; EDX - Data; ECX - Count
test ecx, ecx
jz @@EXIT
PUSH ESI
MOV ESI, EDX file://Data
@@Loop:
MOV EDX, EAX // copy CRC into EDX
LODSB // load next byte into AL
XOR EDX, EAX // put array index into DL
SHR EAX, 8 // shift CRC one byte right
SHL EDX, 2 // correct EDX (*4 - index in array)
XOR EAX, DWORD PTR CRC32Table[EDX] // calculate next CRC value
dec ECX
JNZ @@Loop // LOOP @@Loop
POP ESI
@@EXIT:
End;//Crc32Next
function Crc32Done (Crc32: LongWord): LongWord; register;
Asm
NOT EAX
End;//Crc32Done
<Магическую> таблицу можно хранить в исполняемом файле, но мы, как настоящие программисты, будем формировать её в run-time:
function Crc32Initialization: Pointer;
Asm
push EDI
STD
mov edi, OFFSET CRC32Table+ ($400-4) // Last DWORD of the array
mov edx, $FF // array size
@im0:
mov eax, edx // array index
mov ecx, 8
@im1:
shr eax, 1
jnc @Bit0
xor eax, Crc32Polynomial // <магическое> число - тоже что у
ZIP,ARJ,RAR,:
@Bit0:
dec ECX
jnz @im1
stosd
dec edx
jns @im0
CLD
pop EDI
mov eax, OFFSET CRC32Table
End;//Crc32Initialization
Для удобной работы добавим функцию подсчета Crc32 для Stream'a:
function Crc32Stream (Source: TStream; Count: Longint): LongWord;
var
BufSize, N: Integer;
Buffer: PChar;
Begin
Result:=Crc32Init;
if Count = 0 then begin
Source.Position:= 0;
Count:= Source.Size;
end;
if Count > IcsPlusIoPageSize then BufSize:= IcsPlusIoPageSize else
BufSize:= Count;
GetMem(Buffer, BufSize);
try
while Count <> 0 do begin
if Count > BufSize then N := BufSize else N := Count;
Source.ReadBuffer(Buffer^, N);
Result:=Crc32Next(Result,Buffer^,N);
Dec(Count, N);
end;
finally
Result:=Crc32Done(Result);
FreeMem(Buffer);
end;
End;//Crc32Stream
Получаемый на выходе CRC32 совпадает с генерируемым такими программами как PkZip, ARJ, RAR и многими другими.
И, конечно, тестовая программка:
program Crc32;
{$APPTYPE CONSOLE}
uses
SysUtils,Classes,IcsPlus;
var
FS: TFileStream;
Crc: LongWord;
Begin
if ParamCount<>1 then begin
WriteLn('Crc32 v1.0 Copyright © 2001 by Andrew P.Rybin
[magicode@mail.ru]');
WriteLn(' Usage: crc32 filename');
EXIT;
end;
Crc32Initialization;
FS:= TFileStream.Create(ParamStr(1),fmOpenRead);
try
Crc:=Crc32Stream(FS,0);
WriteLn('Crc: ',IntToHex(Crc,8),' = ',Crc);
finally
FS.FREE;
end;
End.