整理SQL SERVER数据页checksum校验算法
在SQL SERVER2005以上版本中,数据页默认开启checksum,标识为m_flagBits & 0x200 == True,其值m_tornBits位于页头0x3C,4字节。
其算法概述如下:
读8KB进BUF将BUF头部CHECKSUM的4字节值清0uint32checksum=0//初始checksumforiinrange(0,15)://每扇区的初始checksumoverall=0;foriiinrange(0,127)://对当前扇区的每个4字节做累加异或overall=overall^BUF[i][ii];//对每扇区的checksum进行移位,方法为向左移位15-i位,//左边移出的15-i位补到最低位。checksum=checksum^rol(overall,15-i);returnchecksum;//Getschecksum
c源码如下:
//***CODE***//#include<stdio.h>#include<stdlib.h>#defineseed15//Initialseed(forfirstsector)#defineCHAR_BIT8//***PROTOTYPES***//unsignedintpage_checksum(intpage_id,unsignedint*ondisk);unsignedintrol(unsignedintvalue,unsignedintrotation);intmain(intargc,char*argv[]){unsignedintcomputed_checksum;//Vartoretrievecalculatedchecksumunsignedintondisk_checksum;//Vartoretrievechecksumondiskcomputed_checksum=page_checksum(152,&ondisk_checksum);//page_checksumcalltoretrievestoredandcalculatedchecksumforpage152//***PRINTS***//printf("Calculatedchecksum:0x%08x\n",computed_checksum);printf("Ondiskchecksum:0x%08x\n",ondisk_checksum);}unsignedintpage_checksum(intpage_id,unsignedint*ondisk){FILE*fileptr;unsignedinti;unsignedintj;unsignedintchecksum;unsignedintoverall;unsignedint*pagebuf[16][128];//Apointertodescribe2darray[sector][element]fileptr=fopen("C:\\Users\\andre\\Desktop\\teste.mdf","r+b");//Opendummydatafileforbinaryreadfseek(fileptr,page_id*8192,SEEK_SET);//Calculatepageaddressondatafileandpointstoitfread(pagebuf,4,2048,fileptr);//Readpagebufferfclose(fileptr);checksum=0;overall=0;*ondisk=pagebuf[0][15];//Thismeansthattornbitsisstoredonfirstsectorin15thelement,Internalsresearchesunderstandthispagebuf[0][15]=0x00000000;//Fillchecksumfieldwithzeroes(thisfieldwillbediscardedinalgorithm)for(i=0;i<16;i++)//Loopthroughsectors{overall=0;//Resetoverallsumforsectorsfor(j=0;j<128;j++)//Loopthroughelementsinsectori{overall=overall^(unsignedint)pagebuf[i][j];//XORoperationbetweensectorielements}checksum=checksum^rol(overall,seed-i);//Currentchecksumisoverallforsectoricircularshiftedbyseed(15-i)}returnchecksum;//Getschecksum}unsignedintrol(unsignedintvalue,unsignedintrotation){return(value)<<(rotation)|(value)>>(sizeof(int)*CHAR_BIT-rotation)&((1<<rotation)-1);}
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。