• SQL SERVER数据页checksum校验算法整理


    在SQL SERVER2005以上版本中,数据页默认开启checksum,标识为m_flagBits & 0x200 == True,其值m_tornBits位于页头0x3C,4字节。
    其算法概述如下:

    读8KB 进BUF
    将BUF头部 CHECKSUM的4字节值清0
    uint32 checksum = 0 //初始checksumfor i in range(0,15):
             //每扇区的初始checksum
             overall = 0;
            for ii in range(0,127):
                     //对当前扇区的每个4字节做累加异或
                    overall = overall ^ BUF[i][ii];
                    //对每扇区的checksum进行移位,方法为向左移位15-i位,
                    //左边移出的15-i位补到最低位。
                    checksum = checksum ^ rol(overall, 15- i);
    return checksum; //Gets checksum

    c源码如下:

    //***CODE***//#include <stdio.h>#include <stdlib.h>
    #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 on disk
            computed_checksum = page_checksum(152, &ondisk_checksum); //page_checksum call to retrieve stored and calculated checksum for page 152
            //***PRINTS***//
            printf("Calculated checksum: 0x%08x
    ", computed_checksum);
            printf("On disk checksum: 0x%08x
    ", 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][128]; //A pointer to describe 2d array [sector][element]
        fileptr = fopen("C:\Users\andre\Desktop\teste.mdf", "r+b"); //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] = 0x00000000; //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) << (rotation) | (value) >> (sizeof(int) * CHAR_BIT - rotation) & ( (1 << rotation) -1);
    }
  • 相关阅读:
    javaScript的一些兼容性问题
    JavaScript的基本规范
    数组去重的方法有哪些?
    封装on emit off方法(observer)
    对数据进行单元格合并处理的函数
    判断浏览器的内核的函数方法
    bootstrap与vue的区别是什么?(十七)
    Redis介绍及使用(八)
    mysql常用sql语法
    idea使用maven下载jar包,出现证书校验问题问题,unable to find valid certification path to requested target
  • 原文地址:https://www.cnblogs.com/frombyte/p/11315147.html
Copyright © 2020-2023  润新知