It is the division between the data, multipled by 2^n (otherwise 1 byte data is always 0) with the polynomial
x^8+x^5+x^4+1
The bits are considered with the LSByte as first byte (byte 0), MSB as Byte 7,
and bits are reversed as well:imagine to push the bits from the left)
example:
the polynomial itself is 8C80
see info here
1 THEORY )Reversing CRC -- Theory and Practice (2006) by Martin Stigge , Henryk Plötz , Wolf Müller , Jens-Peter Redlich)
2 DATA SHEET) http://www.maxim-ic.com/app-notes/index.mvp/id/27
3 CALCULATOR)http://www.maxim-ic.com/design/tools/appnotes/4600/AN4600-calculator.xls
4 FORUM DISCUSSION with multiple solutions) http://www.ccsinfo.com/forum/viewtopic.php?t=37015
5 SOLUTION crc2) http://www.dattalo.com/technical/software/pic/crc_8bit.c
============ 2 TABLE VERSION===========
static const unsigned char L[16]={0x00,0x5e,0xbc,0xe2,
0x61,0x3f,0xdd,0x83,
0xc2,0x9c,0x7e,0x20,
0xa3,0xfd,0x1f,0x41};
static const unsigned char H[16]={0x00,0x9d,0x23,0xbe,
0x46,0xdb,0x65,0xf8,
0x8c,0x11,0xaf,0x32,
0xca,0x57,0xe9,0x74};
int8 crcf(int8 crc, int8 crc_data)
{
int8 i;
i = (crc_data ^ crc) ;
crc = L[i&0x0F]^H[i>>4];
return crc;
}
=========CRC2 SOLUTION========
=============TABLE DERIVATION=============
void printtableL(){
std::cout<<"L=";
for (int i=0;i<16;i++){
unsigned char crc=0;
if (i & 1)
crc ^= 0x5e;
if(i & 2)
crc ^= 0xbc;
if(i & 4)
crc ^= 0x61;
if(i & 8)
crc ^= 0xc2;
std::cout<<std::hex<<(int)crc<<",";
}
std::cout<<std::endl;
}
void printtableH(){
std::cout<<"H=";
for (int i=0;i<16;i++){
unsigned char crc=0;
if(i & 0x10>>4)
crc ^= 0x9d;
if(i & 0x20>>4)
crc ^= 0x23;
if(i & 0x40>>4)
crc ^= 0x46;
if(i & 0x80>>4)
crc ^= 0x8c;
std::cout<<std::hex<<(int)crc<<",";
}
std::cout<<std::endl;
}
=============TESTING ====================
void print(unsigned char* c,int l,int ident){
for (int i=0;i<ident;i++){
cout<<" ";
}
for (int i=0;i<l;i++){
cout<<(int)c[i];
}
cout<<endl;
}
unsigned char dataReverse(unsigned char c){
unsigned char r=0;
for (int i=0;i<8;i++){
if (c&(1<<i)){
r=r|(1<<(7-i));
}
}
return r;
}
unsigned char trivcrc(const unsigned char* d,int n){
unsigned char buffer[1024];
int c=0;
unsigned char cs=0x31;
unsigned char csbuf[9];
csbuf[0]=1;
for (int b=7;b>=0;b--){
if (cs&(1<<b)){
csbuf[7-b+1]=1;
}else{
csbuf[7-b+1]=0;
}
}
for (int i=0;i<n;i++){
for (int b=7;b>=0;b--){
if (d[i]&(1<<b)){
buffer[c++]=1;
}else{
buffer[c++]=0;
}
}
}
for (int i=0;i<8;i++){
buffer[c++]=0;
}
for (int i=0;i<c-8;i++){
print(buffer,c,0);
print(csbuf,9,i);
if (buffer[i]==1){
for (int j=0;j<9;j++){
buffer[i+j]=buffer[i+j]^csbuf[j];
}
}
}
print(buffer,c,0);
unsigned char r=0;
for (int b=7;b>=0;b--){
if (buffer[c-1-b]){
r=r|(1<<b);
}
}
std::cout<<"r is"<<std::hex<<(int)r<<std::endl;
return r;
}
void bufferReverse(unsigned char* dst,unsigned char* src,int n){
for (int i=0;i<n;i++){
dst[i]=0;
}
for (int b=0;b<n*8;b++){
int it=(b%8);
int ite=b/8;
if (src[ite]&(1<<it))
dst[n-1-ite]|=(1<<(7-it));
}
}
int main(){
unsigned char buff[3];
buff[0]=0x00;
buff[1]=0xF5;
buff[2]=0xF4;
unsigned char revbuff[3];
bufferReverse(revbuff,buff,3);
cout<<hex<<(int)dataReverse(trivcrc(revbuff,3))<<endl;
int8 crc=0;
for (int i=0;i<3;i++){
crc=crc2(crc,buff[2-i]);
}
int8 fcrc=0;
for (int i=0;i<3;i++){
fcrc=crcf(fcrc,buff[2-i]);
}
std::cout<<"fast="<<(int)crc<<endl;
std::cout<<"ffast="<<(int)fcrc<<endl;
}
x^8+x^5+x^4+1
The bits are considered with the LSByte as first byte (byte 0), MSB as Byte 7,
and bits are reversed as well:imagine to push the bits from the left)
example:
the polynomial itself is 8C80
see info here
1 THEORY )Reversing CRC -- Theory and Practice (2006) by Martin Stigge , Henryk Plötz , Wolf Müller , Jens-Peter Redlich)
2 DATA SHEET) http://www.maxim-ic.com/app-notes/index.mvp/id/27
3 CALCULATOR)http://www.maxim-ic.com/design/tools/appnotes/4600/AN4600-calculator.xls
4 FORUM DISCUSSION with multiple solutions) http://www.ccsinfo.com/forum/viewtopic.php?t=37015
5 SOLUTION crc2) http://www.dattalo.com/technical/software/pic/crc_8bit.c
============ 2 TABLE VERSION===========
static const unsigned char L[16]={0x00,0x5e,0xbc,0xe2,
0x61,0x3f,0xdd,0x83,
0xc2,0x9c,0x7e,0x20,
0xa3,0xfd,0x1f,0x41};
static const unsigned char H[16]={0x00,0x9d,0x23,0xbe,
0x46,0xdb,0x65,0xf8,
0x8c,0x11,0xaf,0x32,
0xca,0x57,0xe9,0x74};
int8 crcf(int8 crc, int8 crc_data)
{
int8 i;
i = (crc_data ^ crc) ;
crc = L[i&0x0F]^H[i>>4];
return crc;
}
=========CRC2 SOLUTION========
int8 crc2(int8 crc, int8 crc_data)
{
int8 i;
i = (crc_data ^ crc) ;//& 0xff;
crc = 0;
if(i & 1)
crc ^= 0x5e;
if(i & 2)
crc ^= 0xbc;
if(i & 4)
crc ^= 0x61;
if(i & 8)
crc ^= 0xc2;
if(i & 0x10)
crc ^= 0x9d;
if(i & 0x20)
crc ^= 0x23;
if(i & 0x40)
crc ^= 0x46;
if(i & 0x80)
crc ^= 0x8c;
return(crc);
}
void printtableL(){
std::cout<<"L=";
for (int i=0;i<16;i++){
unsigned char crc=0;
if (i & 1)
crc ^= 0x5e;
if(i & 2)
crc ^= 0xbc;
if(i & 4)
crc ^= 0x61;
if(i & 8)
crc ^= 0xc2;
std::cout<<std::hex<<(int)crc<<",";
}
std::cout<<std::endl;
}
void printtableH(){
std::cout<<"H=";
for (int i=0;i<16;i++){
unsigned char crc=0;
if(i & 0x10>>4)
crc ^= 0x9d;
if(i & 0x20>>4)
crc ^= 0x23;
if(i & 0x40>>4)
crc ^= 0x46;
if(i & 0x80>>4)
crc ^= 0x8c;
std::cout<<std::hex<<(int)crc<<",";
}
std::cout<<std::endl;
}
=============TESTING ====================
void print(unsigned char* c,int l,int ident){
for (int i=0;i<ident;i++){
cout<<" ";
}
for (int i=0;i<l;i++){
cout<<(int)c[i];
}
cout<<endl;
}
unsigned char dataReverse(unsigned char c){
unsigned char r=0;
for (int i=0;i<8;i++){
if (c&(1<<i)){
r=r|(1<<(7-i));
}
}
return r;
}
unsigned char trivcrc(const unsigned char* d,int n){
unsigned char buffer[1024];
int c=0;
unsigned char cs=0x31;
unsigned char csbuf[9];
csbuf[0]=1;
for (int b=7;b>=0;b--){
if (cs&(1<<b)){
csbuf[7-b+1]=1;
}else{
csbuf[7-b+1]=0;
}
}
for (int i=0;i<n;i++){
for (int b=7;b>=0;b--){
if (d[i]&(1<<b)){
buffer[c++]=1;
}else{
buffer[c++]=0;
}
}
}
for (int i=0;i<8;i++){
buffer[c++]=0;
}
for (int i=0;i<c-8;i++){
print(buffer,c,0);
print(csbuf,9,i);
if (buffer[i]==1){
for (int j=0;j<9;j++){
buffer[i+j]=buffer[i+j]^csbuf[j];
}
}
}
print(buffer,c,0);
unsigned char r=0;
for (int b=7;b>=0;b--){
if (buffer[c-1-b]){
r=r|(1<<b);
}
}
std::cout<<"r is"<<std::hex<<(int)r<<std::endl;
return r;
}
void bufferReverse(unsigned char* dst,unsigned char* src,int n){
for (int i=0;i<n;i++){
dst[i]=0;
}
for (int b=0;b<n*8;b++){
int it=(b%8);
int ite=b/8;
if (src[ite]&(1<<it))
dst[n-1-ite]|=(1<<(7-it));
}
}
int main(){
unsigned char buff[3];
buff[0]=0x00;
buff[1]=0xF5;
buff[2]=0xF4;
unsigned char revbuff[3];
bufferReverse(revbuff,buff,3);
cout<<hex<<(int)dataReverse(trivcrc(revbuff,3))<<endl;
int8 crc=0;
for (int i=0;i<3;i++){
crc=crc2(crc,buff[2-i]);
}
int8 fcrc=0;
for (int i=0;i<3;i++){
fcrc=crcf(fcrc,buff[2-i]);
}
std::cout<<"fast="<<(int)crc<<endl;
std::cout<<"ffast="<<(int)fcrc<<endl;
}
No comments:
Post a Comment