Chinaunix首页 | 论坛 | 博客
  • 博客访问: 224528
  • 博文数量: 469
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 4725
  • 用 户 组: 普通用户
  • 注册时间: 2016-08-02 14:16
文章分类

全部博文(469)

文章存档

2024年(34)

2023年(218)

2022年(181)

2020年(12)

2019年(24)

我的朋友

分类: SQLServer

2019-08-07 15:05:08

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

点击(此处)折叠或打开

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

点击(此处)折叠或打开

  1. //***CODE***//#include <stdio.h>#include <stdlib.h>
  2. #define seed 15 //Initial seed(for first sector)#define CHAR_BIT 8
  3. //***PROTOTYPES***//unsigned int page_checksum(int page_id, unsigned int *ondisk);unsigned int rol(unsigned int value, unsigned int rotation);
  4. int main(int argc, char *argv[]) {

  5.     unsigned int computed_checksum; //Var to retrieve calculated checksum
  6.     unsigned int ondisk_checksum; //Var to retrieve checksum on disk

  7.         computed_checksum = page_checksum(152, &ondisk_checksum); //page_checksum call to retrieve stored and calculated checksum for page 152

  8.         //***PRINTS***//
  9.         printf("Calculated checksum: 0x%08x\n", computed_checksum);
  10.         printf("On disk checksum: 0x%08x\n", ondisk_checksum);

  11. }
  12. unsigned int page_checksum(int page_id, unsigned int *ondisk){

  13.     FILE *fileptr;
  14.     unsigned int i;
  15.     unsigned int j;
  16.     unsigned int checksum;
  17.     unsigned int overall;
  18.     unsigned int *pagebuf[16][128]; //A pointer to describe 2d array [sector][element]

  19.     fileptr = fopen("C:\\Users\\andre\\Desktop\\teste.mdf", "r+b"); //Open dummy data file for binary read

  20.     fseek(fileptr, page_id * 8192, SEEK_SET); //Calculate page address on data file and points to it

  21.     fread(pagebuf, 4, 2048, fileptr); //Read page buffer

  22.     fclose(fileptr);

  23.     checksum = 0;
  24.     overall = 0;

  25.     *ondisk = pagebuf[0][15]; //This means that torn bits is stored on first sector in 15th element, Internals researches understand this

  26.     pagebuf[0][15] = 0x00000000; //Fill checksum field with zeroes (this field will be discarded in algorithm)

  27.     for (i = 0; i < 16; i++) //Loop through sectors
  28.     {

  29.         overall = 0; //Reset overall sum for sectors

  30.         for (j = 0; j < 128; j++) //Loop through elements in sector i
  31.         {
  32.             overall = overall ^ (unsigned int)pagebuf[i][j]; //XOR operation between sector i elements
  33.         }

  34.         checksum = checksum ^ rol(overall, seed - i); //Current checksum is overall for sector i circular shifted by seed (15 - i)
  35.     }

  36.     return checksum; //Gets checksum

  37. }
  38. unsigned int rol(unsigned int value, unsigned int rotation){
  39.     return (value) << (rotation) | (value) >> (sizeof(int) * CHAR_BIT - rotation) & ( (1 << rotation) -1);
  40. }
阅读(1046) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~