CRC-4 CRC-6 CRC-8 CRC-10
Принимаются любые советы и ссылки. Заранее спасибо!
On 2002-08-27 1216, Klop wrote
Пожалуйста, помогите кто может нетабличной реализацией процедур для вычисления CRC (не 16 не 32).
Принимаются любые советы и ссылки. Заранее спасибо!
Вот бестабличный алгоритм для CRC-16(правда, на СИ)
WORD Get_NewCRC(WORD Polinom,char *TestStr)
{
WORD NewCRC;
BYTE CurrChar;
int index,index8bit;
BYTE BitCRC,BitChar;
NewCRC=0xFFFF;
index=0;
NextChar
CurrChar=(BYTE)TestStr[index];
index8bit=8;
NextBit
BitCRC=NewCRC>>15;
BitChar=CurrChar>>7;
NewCRC=NewCRC<<1;
CurrChar=CurrChar<<1;
if (BitCRC!=BitChar) NewCRC=NewCRC^Polinom;
index8bit--;
if (index8bit!=0) goto NextBit;
index++;
if (index<strlen(TestStr)) goto NextChar;
return(NewCRC);
}
Polinom - например, x^12+x^5+x^0(0x1021).
Сам понимаешь, что лучше его написать на асме. Но не суть. Он рассчитан на поток байт(входные данные), но на самом деле он берет первый байт, перебирает биты от старшего к младшему, переходит к следующему байту и тд.
При этом он использует 16 бит полинома и накопитель - CRC тоже 16 бит.
Если хочешь CRC4, то следует работать с накопителем(CRC) как с 4-х битным числом, и полином представляет собой тоже 4-х битное число (т.е. для CRC16 полином - 0x1021, а для CRC4 уже 0x1021 & 0x000F = 0x0001)
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <math.h>
#include <mem.h>
int len;
const int LDIV=9;
int howmany(int x)
{
int y;
double log2;
log2=log((double)x)/M_LN2;
log2++;
y=(int)log2+LDIV-1;
return y;
}
void itobin(int x,int *a)
{
int i,y,r;
for (i=0;i<len;i++) a=0;
i=1;
y=x;
do
{
r=y%2;
if (r==0) a[len-LDIV+1-i]=0; else a[len-LDIV+1-i]=1;
y/=2;
i++;
}
while(y);
}
void main()
{
int w=1,i,j,k=0,first=1,all,ideal=0;
int ost[9]={0,0,0,0,0,0,0,0,0};
int bufer[9]={0,0,0,0,0,0,0,0,0};
int crc[8]={0,0,0,0,0,0,0,0};
int finalcrc[8]={0,0,0,0,0,0,0,0};
const dvd[9]={1,0,0,0,0,0,0,0,1};
int *a;
FILE *f;
puts("Would you like to see all calculations for every byte?(y/n)");
puts("In opposing case you will see only results for every byte.");
all=getch();
if (all==121) all=1; else all=0;
f=fopen("data","r");
while(w!=EOF)
{
clrscr();
w=fgetc(f);
if (w<0) break;
printf("Symbol %c ASCII %d",w,w);
len=howmany(w);
printf("\n%d\n",len);
a=(int*)calloc(len,sizeof(int));
itobin(w,a);
for (i=0;i<len;i++) printf("%d",a);
puts("\n");
for (i=0;i<LDIV;i++) bufer=a;
if (all) for (i=0;i<LDIV;i++) printf("%d",dvd);
if (all) puts("");
j=0;
while(j<len-LDIV+1)
{
for (i=0;i<LDIV;i++) {ost=bufer^dvd;}
if (all) for (i=0;i<LDIV;i++) printf("%d",ost);
k=0;
while (!ost[k]) {k++; j++;}
for (i=0;i<LDIV-k;i++) bufer=ost[i+k];
for (i=LDIV-k;i<LDIV;i++) bufer=0;
if (all) printf("\n%d",k);
if (all) puts("");
if (all) for (i=0;i<LDIV;i++) printf("%d",bufer);
if (all) puts("");
if (all) getch();
}
puts("");
ideal=LDIV-1-len+j;
if (all) printf("%d\n",ideal);
for(i=0;i<LDIV-1;i++) crc=0;
for(i=0;i<LDIV-1;i++) crc[ideal+i]=bufer;
printf("CRC of current byte ");
for (i=0;i<LDIV-1;i++) printf("%d",crc);
if (first) for (i=0;i<LDIV-1;i++) {finalcrc=crc;}
else for (i=0;i<LDIV-1;i++) {finalcrc^=crc;}
printf("\nCRC of all calculated bytes ");
for (i=0;i<LDIV-1;i++) printf("%d",finalcrc);
first=0;
getch();
}
fclose(f);
puts("Final CRC");
for (i=0;i<LDIV-1;i++) printf("%d",finalcrc);
getch();
free(a);
}