ToB企服应用市场:ToB评测及商务社交产业平台

标题: 5.0 CRC32校验技术概述 [打印本页]

作者: 大连密封材料    时间: 2023-9-21 13:13
标题: 5.0 CRC32校验技术概述
CRC校验技术是用于检测数据传输或存储过程中是否出现了错误的一种方法,校验算法可以通过计算应用与数据的循环冗余校验(CRC)检验值来检测任何数据损坏。通过运用本校验技术我们可以实现对特定内存区域以及磁盘文件进行完整性检测,并以此来判定特定程序内存是否发生了变化,如果发生变化则拒绝执行,通过此种方法来保护内存或磁盘文件不会被非法篡改。总之,内存和磁盘中的校验技术都是用于确保数据和程序的完整性和安全性的重要技术。
以下是一些关于内存和磁盘中的CRC校验技术的详细信息:
首先我们需要自行实现一个CRC算法,通常情况下CRC算法需要经历三个步骤,生成CRC表格,读取数据并计算CRC,计算最终的CRC值,这个实现原理可细化为如下三步;
根据上述描述读者应该可以理解CRC32的工作原理,如下代码是实现CRC32的核心算法。该算法生成一个256个元素的CRC表,在输入数据块上执行一系列按位运算。CRC32算法将输入的数据块视为位串,并产生一个唯一的32位输出,该输出可以用于验证数据的完整性和一致性等方面。
在该代码中,CRC表是动态生成的,采用了多项式0xEDB88320L。然后,该算法使用crcTmp2变量来存储中间CRC值,对每个字节进行一系列运算,以生成最终的CRC32值。返回值为计算出的CRC32值。
  1. // 定义一个指向字节缓冲区的指针ptr和字节缓冲区的大小Size,计算并返回CRC32值
  2. DWORD CRC32(BYTE* ptr, DWORD Size)
  3. {
  4.   DWORD crcTable[256], crcTmp1;
  5.   // 动态生成CRC-32表
  6.   // 生成一个长度为256的CRC表格,共含有256个元素
  7.   for (int i = 0; i<256; i++)
  8.   {
  9.     crcTmp1 = i;
  10.     // 每个元素计算8个字节
  11.     for (int j = 8; j>0; j--)
  12.     {
  13.       if (crcTmp1 & 1) crcTmp1 = (crcTmp1 >> 1) ^ 0xEDB88320L; // 判断是否需要异或 0xEDB88320L
  14.       else crcTmp1 >>= 1;                                      // 如果不需要异或,则每次将该数右移一位
  15.     }
  16.     // 将得到的结果存放在CRC表格中
  17.     crcTable[i] = crcTmp1;
  18.   }
  19.   
  20.   // 计算CRC32值
  21.   // 使用while循环来逐步处理字节块
  22.   DWORD crcTmp2 = 0xFFFFFFFF;
  23.   while (Size--)
  24.   {
  25.     // 将crcTmp2右移8位,并将最高8位数据清零
  26.     crcTmp2 = ((crcTmp2 >> 8) & 0x00FFFFFF) ^ crcTable[(crcTmp2 ^ (*ptr)) & 0xFF];
  27.     ptr++; // 处理下一个字节
  28.   }
  29.   // 将最终的crcTmp2值反转位顺序,并执行XOR运算,返回最终的CRC32值
  30.   return (crcTmp2 ^ 0xFFFFFFFF);
  31. }
复制代码
上述代码则是CRC32生成的核心实现流程,读者在使用时只需要调用封装好的CRC32()函数并依次传入字符串及字符串长度,即可完成流程调用。但此处读者需要注意,CRC32不是加密算法,不能保证数据的安全性。其只能作为较小数据块的简单完整性检查和错误检测的一种手段。
  1. int main(int argc, char *argv[])
  2. {
  3.     char* ptr = "hello lyshark";
  4.     DWORD size = sizeof("hello lyshark");
  5.     printf("原始字符串: %s \n", ptr);
  6.     DWORD ret = CRC32((BYTE *)ptr, size);
  7.     printf("CRC32 = %x \n", ret);
  8.     system("pause");
  9.     return 0;
  10. }
复制代码
当调用上述代码时读者应该可以看到hello lyshark字符串的CRC32码,输出效果如下图所示;

上述代码片段仅用于验证内存字符串,如果读者需要验证磁盘文件的特征码则首先需要通过CreateFile打开文件得到文件句柄,接着通过ReadFile将整个文件读入到内存,最后再次调用CRC32(pFile, dwSize)实现验证文件的CRC数据,但此方法仅用于验证小文件,如果文件过大则可能会耗费大量的内存。
  1. int main(int argc, char* argv[])
  2. {
  3.     char *FileName = "d://lyshark.exe";
  4.     // 验证文件是否存在
  5.     if (GetFileAttributes(FileName) == 0xFFFFFFFF)
  6.     {
  7.         return 0;
  8.     }
  9.     // 打开文件
  10.     HANDLE hFile = CreateFile(FileName, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
  11.     // 得到文件长度
  12.     DWORD dwSize = GetFileSize(hFile, NULL);
  13.     // 开辟一段内存空间
  14.     BYTE *pFile = (BYTE*)malloc(dwSize);
  15.     // 将数据读入文件
  16.     DWORD dwNum = 0;
  17.     ReadFile(hFile, pFile, dwSize, &dwNum, 0);
  18.     // 计算CRC32
  19.     DWORD dwCrc32 = CRC32(pFile, dwSize);
  20.     if (pFile != NULL)
  21.     {
  22.         printf("文件名 = %s \n", FileName);
  23.         printf("文件长度 = %d \n", dwSize);
  24.         printf("分配内存 = 0x%x \n", pFile);
  25.         printf("CRC32 = 0x%x \n", dwCrc32);
  26.         free(pFile);
  27.         pFile = NULL;
  28.     }
  29.     system("pause");
  30.     return 0;
  31. }
复制代码
上述代码运行后则可输出d://lyshark.exe文件的CRC32值,输出效果如下图所示;

本文作者: 王瑞
本文链接: https://www.lyshark.com/post/68b9f1ba.html
版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4