CRC32校验和(Win32, C++)

48 篇文章 0 订阅

CCrc32Utils.h

#pragma once

#include <string>
#include <stdint.h>

#ifdef _UNICODE
using _tstring = std::wstring;
#else
using _tstring = std::string;
#endif

class CCrc32Utils
{
public:

    static uint32_t GetCrc32Value(const void* lpData, size_t nSize);
    static _tstring GetCrc32Str(const void* lpData, size_t nSize, bool bUpper = false);
    static uint32_t GetFileCrc32Value(const _tstring& strFilePath);
    static _tstring GetFileCrc32Str(const _tstring& strFilePath, bool bUpper = false);

    static uint32_t GetPartCrc32(uint32_t crcInit, const void* lpData, size_t byteSize);
    static _tstring GetStrFromValue(uint32_t uCrc32, bool bUpper = false);

private:

    static void InitCrc32Table(void);
    static uint32_t GetCrc32(const uint8_t* lpData, size_t byteSize);
    static uint32_t GetCrc32Data(uint32_t crcInit, const uint8_t* lpData, size_t byteSize);
};

CCrc32Utils.cpp

#include "CCrc32Utils.h"
#include <fstream>

#define CRC32_POLY          (0xEDB88320L)           // CRC32标准
#define CRC32_TABLE_SIZE    (256)                   // CRC查询表大小
#define CRC32_BLOCK_SIZE    (1024 * 1024 * 64)      // CRC缓冲块大小

static uint32_t g_Crc32Table[CRC32_TABLE_SIZE] = { 0 }; // CRC查询表
static bool g_bInitFlag = false;                        // CRC查询表初始化标记

#define _count_of(_array) (sizeof(_array) / sizeof(_array[0]))

uint32_t CCrc32Utils::GetCrc32Value(const void* lpData, size_t nSize)
{
    if (!g_bInitFlag)
    {
        InitCrc32Table();
        g_bInitFlag = true;
    }

    return GetCrc32((uint8_t*)lpData, nSize);
}

_tstring CCrc32Utils::GetCrc32Str(const void* lpData, size_t nSize, bool bUpper/* = false*/)
{
    return GetStrFromValue(GetCrc32Value((uint8_t*)lpData, nSize), bUpper);
}

uint32_t CCrc32Utils::GetPartCrc32(uint32_t crcInit, const void* lpData, size_t byteSize)
{
    if (0 == byteSize)
    {
        return crcInit;
    }

    if (!g_bInitFlag)
    {
        InitCrc32Table();
        g_bInitFlag = true;
    }

    return GetCrc32Data(crcInit, (uint8_t*)lpData, byteSize);
}

uint32_t CCrc32Utils::GetFileCrc32Value(const _tstring& strFilePath)
{
    if (!g_bInitFlag)
    {
        InitCrc32Table();
        g_bInitFlag = true;
    }

    uint32_t dwCrc32 = 0;
    std::ifstream inputFile(strFilePath.c_str(), std::ios::binary | std::ios::in);
    if (!inputFile.is_open())
    {
        return false;
    }

    uint8_t* lpBuf = new (std::nothrow) uint8_t[CRC32_BLOCK_SIZE];
    if (nullptr == lpBuf)
    {
        return dwCrc32;
    }

    while (!inputFile.eof())
    {
        inputFile.read((char*)lpBuf, CRC32_BLOCK_SIZE);
        size_t nByteSize = (size_t)inputFile.gcount();
        if (nByteSize > 0)
        {
            dwCrc32 = GetCrc32Data(dwCrc32, lpBuf, nByteSize);
        }
    }

    inputFile.close();
    if (nullptr != lpBuf)
    {
        delete[]lpBuf;
    }

    return dwCrc32;
}

_tstring CCrc32Utils::GetFileCrc32Str(const _tstring& strFilePath, bool bUpper/* = false*/)
{
    return GetStrFromValue(GetFileCrc32Value(strFilePath), bUpper);
}

_tstring CCrc32Utils::GetStrFromValue(uint32_t uCrc32, bool bUpper/* = false*/)
{
#ifdef _UNICODE
    wchar_t szBuf[32] = { 0 };
#else
    char szBuf[32] = { 0 };
#endif

#ifdef _UNICODE
    _snwprintf_s(szBuf, _count_of(szBuf), bUpper ? L"%0.8X" : L"%0.8x", uCrc32);
#else
    snprintf(szBuf, _count_of(szBuf), bUpper ? "%0.8X" : "%0.8x", uCrc32);
#endif

    return szBuf;
}

void CCrc32Utils::InitCrc32Table(void)
{
    for (uint32_t i = 0; i < _count_of(g_Crc32Table); i++)
    {
        uint32_t crc = i;
        for (int j = 0; j < 8; j++)
        {
            if (crc & 0x00000001L)
                crc = (crc >> 1) ^ CRC32_POLY;
            else
                crc = crc >> 1;
        }
        g_Crc32Table[i] = crc;
    }
}

uint32_t CCrc32Utils::GetCrc32(const uint8_t* lpData, size_t byteSize)
{
    uint32_t dwCrc32 = 0;
    size_t nBlockSize = byteSize > CRC32_BLOCK_SIZE ? CRC32_BLOCK_SIZE : byteSize;
    uint8_t* lpBase = (uint8_t*)lpData;

    while (byteSize > 0)
    {
        dwCrc32 = GetCrc32Data(dwCrc32, lpBase, nBlockSize);
        lpBase += nBlockSize;
        byteSize -= nBlockSize;

        nBlockSize = byteSize > CRC32_BLOCK_SIZE ? CRC32_BLOCK_SIZE : byteSize;
    }

    return dwCrc32;
}

uint32_t CCrc32Utils::GetCrc32Data(uint32_t crcInit, const uint8_t* lpData, size_t byteSize)
{
    uint32_t crc = crcInit ^ 0xffffffff;

    while (byteSize--)
    {
        crc = (crc >> 8) ^ g_Crc32Table[(crc & 0xff) ^ *lpData++];
    }

    return crc ^ 0xffffffff;
}

 

 

  • 9
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值