On the collation of checksum check algorithm for SQL SERVER data pages
Checksum check algorithm for SQL SERVER data pages
In versions above SQL SERVER2005, checksum is enabled by default on the data page, identified as m_flagBits & 0x200 = = True, and its value m_tornBits is located in the header 0x3CMagi 4 bytes.
The algorithm is summarized as follows:
Read 8KB into BUF to make the 4-byte value of the BUF header CHECKSUM clear 0uint32 checksum = 0 / / initial checksumfor i in range (0Magne15): / / initial checksum overall of each sector = 0; for ii in range (0127): / / A cumulative difference or overall = overall ^ BUF [I] [ii] to each 4 bytes of the current sector / / A pair of checksum of each sector is shifted by shifting 15muri bits to the left, and / / the 15muri bits moved to the left are added to the lowest bit. Checksum = checksum ^ rol (overall, 15-I); return checksum; / / Gets checksum
C source code is as follows:
/ / * CODE***//#include # include # define seed 15 / / Initial seed (for first sector) # define CHAR_BIT 8 / / * PROTOTYPES***//unsigned int page_checksum (int page_id, unsigned int * ondisk); unsigned int rol (unsigned int value, unsigned int rotation); int main (int argc, char * argv []) {unsigned int computed_checksum; / / Var to retrieve calculated checksum unsigned int ondisk_checksum / / Var to retrieve checksum ondisk computed_checksum = page_checksum (152, & ondisk_checksum); / / page_checksum call to retrieve stored and calculated checksum for page 152 / / * PRINTS***// printf ("Calculated checksum: 0xx\ n", computed_checksum); printf ("On disk checksum: 0xx\ n", ondisk_checksum);} unsigned int page_checksum (int page_id, unsigned int * ondisk) {FILE * fileptr; unsigned int i Unsigned int j; unsigned int checksum; unsigned int overall; unsigned int * pagebuf [16]; / / A pointer to describe 2d array [sector] [element] fileptr = fopen ("C:\\ Users\\ andre\\ Desktop\\ teste.mdf"); / / Open dummy data file for binary read fseek (fileptr, page_id * 8192, SEEK_SET); / / Calculate page address on data file and points to it fread (pagebuf, 4, 2048, fileptr) / / Read page buffer fclose (fileptr); checksum = 0; overall = 0; * ondisk = pagebuf [0] [15]; / / This means that torn bits is stored on first sector in 15th element, Internals researches understand this pagebuf [0] [15] = 0x000000000; / / Fill checksum field with zeroes (this field will be discarded in algorithm) for (I = 0; I
< 16; i++) //Loop through sectors { overall = 0; //Reset overall sum for sectors for (j = 0; j < 128; j++) //Loop through elements in sector i { overall = overall ^ (unsigned int)pagebuf[i][j]; //XOR operation between sector i elements } checksum = checksum ^ rol(overall, seed - i); //Current checksum is overall for sector i circular shifted by seed (15 - i) } return checksum; //Gets checksum}unsigned int rol(unsigned int value, unsigned int rotation){ return (value) >(sizeof (int) * CHAR_BIT-rotation) & (1