Существует клиент и сервер, которые обмениваются данными по сети. В конце каждого пакета имеется контр.сумма. Не располагаю описанием алгоритма её расчета, но есть необходимость его узнать. У меня есть список пакетов(около 260 тысяч штук).На основе анализа этих пакетов составил функцию, которая вычисляет эту сумму, но в некоторых пакетах она всё же не сходится(эти пакеты посылались на сервер еще несколько раз и в разном порядке и контрольная сумма в них действительно рассчитывается НЕ по моему алгоритму, так что это исключает возможность того что пакеты некорректны). Помогите пожалуйста. результат программы 0.39% not good списки пакетов: http://rghost.ru/4766108 все пакеты http://rghost.ru/4766189 результат программы(пакеты где контр.сумма рассчитана с ошибкой) Код (Text): #include <stdio.h> unsigned short calc_crc(unsigned char* bytes) { unsigned short real_crc=0x0000; unsigned short tmp_crc=0x0000; for(int i=2;i<7;i++) { tmp_crc = (bytes[i])<<(6-i); real_crc=(real_crc + tmp_crc); } while(real_crc>0xFF) { real_crc = ((real_crc & 0xFF00)>>8) + (real_crc & 0x00FF); } return real_crc; } void main(void) { unsigned char bytes[9]; int number=0,all=0,bad=0; unsigned short __CRC; FILE *file = fopen("list.txt","r"); FILE *file_res = fopen("list_res.txt","w+"); while(!feof(file)) { all++; fscanf(file,"%d %hx %hx %hx %hx %hx %hx %hx %hx %hx\n",&number,&bytes[0],&bytes[1],&bytes[2],&bytes[3],&bytes[4],&bytes[5],&bytes[6],&bytes[7],&bytes[8]); __CRC = calc_crc(bytes); if(bytes[7] != __CRC) { bad++; fprintf(file_res,"%06d 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x : 0x%02x\n",bad,bytes[0],bytes[1],bytes[2],bytes[3],bytes[4],bytes[5],bytes[6],bytes[7],bytes[8],__CRC); } } printf("%03.2f%% not good\n",((float)bad/(float)all)*100.0); fclose(file_res); fclose(file); scanf("%d",&number); }
hypertonyc Похоже на пакеты укороченной длины с контрольной суммой в предпоследнем байте. А последний байт может сигнатура или просто мусор.
Не вижу в выявленной закономерности никакого смысла, но все исключения попадают под три правила : Код (Text): for i:=1 to 5 do begin u:=u + (q[i] shl (5-i)); if (i=3) and (u=$7FC) then u:=0; if (i=5) and (u=$7FA) then u:=0; if (i=5) and (u=$3FE) then u:=0; end; Может на что-то натолкнет. Извини, нумерация байт другая (u=real_crc).
Действительно с такой функцией 0.00% not good Код (Text): unsigned short calc_crc(unsigned char* bytes) { unsigned short real_crc=0x0000; unsigned short tmp_crc=0x0000; for(int i=2;i<7;i++) { tmp_crc = (bytes[i])<<(6-i); real_crc=(real_crc + tmp_crc); if ((i==4) && (real_crc==0x7FC)) real_crc=0; if ((i==6) && (real_crc==0x7FA)) real_crc=0; if ((i==6) && (real_crc==0x3FE)) real_crc=0; } while(real_crc>0xFF) { real_crc = ((real_crc & 0xFF00)>>8) + (real_crc & 0x00FF); } return real_crc; } ви заметили что первые два байта и последний AF FF FA...похожи байты на те, что в условиях(if)...может нужна маска какая-нибудь( на что-нибудь )?
hypertonyc есть подозрение, что алгоритм там примерно такой: Код (Text): s=0 for i=2 to 6 add s,s adc s,b[i]
если я всё правильно понял, то вы предлагаете такой код: Код (Text): unsigned short calc_crc(unsigned char* bytes) { unsigned short real_crc=0x0000; unsigned short tmp_crc=0x0000; for(int i=2;i<7;i++) { tmp_crc=bytes[i]; _asm { mov ax,real_crc add ax,ax mov bx,tmp_crc adc ax,bx mov real_crc,ax } } while(real_crc>0xFF) { real_crc = ((real_crc & 0xFF00)>>8) + (real_crc & 0x00FF); } return real_crc; } результат программы как и в самом начале - 0.39% not good
hypertonyc неа, сумма восьмибитная, если на си, то можно так: Код (Text): unsigned char s=0; for(int i=2;i<7;i++) s+=s+b[i]+(s>>7);
62.77% not good =| причем если на результирующий файл глянуть то получается что где-то двойка теряется... в ошибочных пакетах сумма отличается на 2 от рассчитанной
Кстати, если "коррекция" нужна только на шагах, отличающихся с шагом 2, то может быть первично сумма считается 16-битная с коррекцией ? (а потом на последнем шаге ее старший и младший байты складываются)
Спасибо всем за участие. Особая благодарность Black_mirror, он то и расколол алгоритм. "байт суммы расширяется до слова, прибавляется к самому себе, потом к нему добавляется расширенный байт из массива, а дальше к младшему байту суммы добавляется старший, а потом младший байт используется в следующей итерации" Тема закрыта.