> 文章列表 > C语言CRC-32 MPEG-2格式校验函数

C语言CRC-32 MPEG-2格式校验函数

C语言CRC-32 MPEG-2格式校验函数

C语言CRC-32 MPEG-2格式校验函数

CRC-32校验产生4个字节长度的数据校验码,通过计算得到的校验码和获得的校验码比较,用于验证获得的数据的正确性。基本的CRC-32校验算法实现,参考: C语言标准CRC-32校验函数

不同应用规范通过对输入数据前处理和输出数据后处理的方式不同,又产生了不同的应用规范校验函数,这里介绍MPEG-2格式的CRC-32校验函数。MPEG-2格式对输入数据,只有预置值为0XFFFF(当做最初的余数)的前处理。

生成多项式为x^32 + x^26 + x^23 + x^22 + x^16 + x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x^1 + 1
由于反向算法更适合于有输入字节倒位序和输出整体数据倒位序的情况,这里只介绍正向算法。

正向算法

正向算法是符合标准CRC-32的计算理论,从左向右计算,也即计算过程中移位时,向左移出。几种正向算法的实现如下:

CRC-32 MPEG-2格式校验函数一(8位输入数据格式,64位装载计算):

#include <stdio.h>
#include <stdlib.h>
uint32_t PY_CRC_32_MPEG_2(uint8_t *di, uint32_t len)
{uint64_t crc_poly = 0x104C11DB7;  //X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+1 total 33 effective bits. Computed total data shall be compensated 32-bit '0' before CRC computing.uint8_t *datain;uint64_t cdata = 0; //Computed total datauint64_t data_t = 0; //Process data of CRC computinguint16_t index_t = 63;  ///bit shifting index for initial '1' searchinguint16_t index = 63;    //bit shifting index for CRC computinguint8_t rec = 0; //bit number needed to be compensated for next CRC computinguint32_t cn=(len+4)/4;uint32_t cr=(len+4)%4;uint32_t j;datain = malloc(len+4);for(j=0;j<len;j++){datain[j]=di[j];}datain[len]=0; datain[len+1]=0; datain[len+2]=0; datain[len+3]=0;//Compensate 32-bit '0' for input datadatain[0] ^= 0xff; datain[1] ^= 0xff; datain[2] ^= 0xff; datain[3] ^= 0xff;if(len<=4)   //Mount data for only one segment{for(j=0;j<=(len+3);j++){cdata = (cdata<<8);cdata = cdata|datain[j];}cn = 1;}else{if(cr==0){cr = 8;cn--;}else if(cr==1){cr = 5;}else if(cr==2){cr = 6;}else if(cr==3){cr = 7;}else;for(j=0;j<cr;j++){cdata = (cdata<<8);cdata = cdata|datain[j];}}do{cn--;while(index_t>0){if( (cdata>>index_t)&1 ){index = index_t;index_t = 0;data_t |= (cdata>>(index-32));{data_t = data_t ^ crc_poly;}while((index!=0x5555)&&(index!=0xaaaa)){for(uint8_t n=1;n<33;n++){if ((data_t>>(32-n))&1) {rec = n;break;}if (n==32) rec=33;}if((index-32)<rec){data_t = data_t<<(index-32);data_t |=  (uint64_t)((cdata<<(64-(index-32)))>>(64-(index-32)));index = 0x5555;}else{for(uint8_t i=1;i<=rec;i++){data_t = (data_t<<1)|((cdata>>(index-32-i))&1) ;}if(rec!= 33){data_t = data_t ^ crc_poly;index -= rec;}else{data_t = 0;index_t = index-32-1;index = 0xaaaa;}}}if(index==0x5555) break;}else{index_t--;if(index_t<32) break;}}if(cn>0) //next segment{cdata = data_t&0x00ffffffff;for(uint8_t k=0;k<4;k++){cdata = (cdata<<8);cdata = cdata|datain[j++];}data_t = 0;index_t = 63;  ///bit shifting index for initial '1' searchingindex = 63;    //bit shifting index for CRC computingrec = 0; //bit number needed to be compensated for next CRC computing}}while(cn>0);free(datain);return (uint32_t)data_t;
}

CRC-32 MPEG-2格式校验函数二(8位输入数据格式):

#include <stdio.h>
#include <stdlib.h>
uint32_t PY_CRC_32_S_MPEG_2(uint8_t *di, uint32_t len)
{uint32_t crc_poly = 0x04C11DB7;  //X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+1 total 16 effective bits without X^32. Computed total data shall be compensated 32-bit '0' before CRC computing.uint32_t clen = len+4;uint8_t cdata[clen] ;memcpy(cdata, di, len); cdata[len]=0; cdata[len+1]=0; cdata[len+2]=0; cdata[len+3]=0;cdata[0] ^= 0xff; cdata[1] ^= 0xff; cdata[2] ^= 0xff; cdata[3] ^= 0xff;uint32_t data_t =  (((uint32_t)cdata[0]) << 24) +  (((uint32_t)cdata[1]) << 16) + (((uint32_t)cdata[2]) << 8) + cdata[3]; //CRC registerfor (uint32_t i = 4; i < clen; i++){for (uint8_t j = 0; j <= 7; j++){if(data_t&0x80000000)data_t = ( (data_t<<1) | ( (cdata[i]>>(7-j))&0x01) ) ^ crc_poly;elsedata_t = ( (data_t<<1) | ( (cdata[i]>>(7-j))&0x01) ) ;}}return data_t;
}

CRC-32 MPEG-2格式校验函数三(32位输入数据格式):

uint32_t PY_CRC_32_T32_MPEG_2(uint32_t *di, uint32_t len)
{uint32_t crc_poly = 0x04C11DB7;  //X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+1 total 32 effective bits without X^32.//uint32_t data_t = 0; //CRC registeruint32_t data_t = 0xffffffff; //CRC registeruint32_t cdata[len];for(uint32_t j=0;j<len;j++){cdata[j] = (di[j]>>24) | ((di[j]&0x00ff0000)>>8) |  ((di[j]&0x0000ff00)<<8) | (di[j]<<24) ;}//cdata[0] ^= 0xffffffff;for(uint32_t i = 0; i < len; i++){data_t ^= cdata[i]; //32-bit datafor (uint8_t j = 0; j < 32; j++){if (data_t & 0x80000000)data_t = (data_t << 1) ^ crc_poly;elsedata_t <<= 1;}}return (data_t);
}

CRC-32 MPEG-2格式校验函数四(8位输入数据格式):

uint32_t PY_CRC_32_T8_MPEG_2(uint8_t *di, uint32_t len)
{uint32_t crc_poly = 0x04C11DB7;  //X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+1 total 32 effective bits without X^32.uint32_t data_t = 0; //CRC registeruint32_t clen = len+4;uint8_t cdata[clen] ;memcpy(cdata, di, len); cdata[len]=0; cdata[len+1]=0; cdata[len+2]=0; cdata[len+3]=0;cdata[0] ^= 0xff; cdata[1] ^= 0xff; cdata[2] ^= 0xff; cdata[3] ^= 0xff;for(uint32_t i = 0; i < len; i++){data_t ^= cdata[i]<<24; //8-bit datafor (uint8_t j = 0; j < 8; j++){if (data_t & 0x80000000)data_t = (data_t << 1) ^ crc_poly;elsedata_t <<= 1;}}return (data_t);
}

算法验证

4种算法结果相同:
C语言CRC-32 MPEG-2格式校验函数

通过在线CRC工具对照验证成功:
C语言CRC-32 MPEG-2格式校验函数

–End–