experiment : convert a string to crc32
来源:互联网 发布:有hao123软件 编辑:程序博客网 时间:2024/05/18 15:24
今天工作任务中遇到一个分支任务, 从系统上层传来一个GUID样子的系统内唯一标识用的字符串, 传到驱动后, 只接受一个DWORD值. 想想需要将这个字符串变成DWORD, 那CRC32好了.
从CodeProject上找了一个类CCrc32Dynamic, http://www.codeproject.com/Articles/1671/CRC32-Generating-a-checksum-for-a-file
但是原版Demo是操作文件的, 算一个文件的CRC32. 改了一下CCrc32Dynamic, 添加了一个接口BufferCrc32, 来计算字符串或Buffer的CRC32值.
使用起来很方便.
工程下载点: string2crc32
使用示例:
// string2crc32.cpp : Defines the entry point for the console application.//#include "stdafx.h"#include <windows.h>#include <tchar.h>#include <string>#include <vector>#include <time.h>#include "crc/Crc32Dynamic.h"VOIDfnTest();int _tmain(int argc, _TCHAR* argv[]){size_tnCnt=0;for(nCnt = 0; nCnt < 6; nCnt++){fnTest();}/// run results/**0xfcc50d330xfcc50d330xfcc50d330xfcc50d330xfcc50d330xfcc50d33*/getchar();return 0;}VOIDfnTest(){DWORDdwCrc32=0;TCHARszMsg[_MAX_PATH];::ZeroMemory(szMsg, sizeof(szMsg));_tcscpy(szMsg, _T("12345"));/// BufferCrc32 这个接口使用起来很舒服BufferCrc32((BYTE *)szMsg, _tcslen(szMsg) * sizeof(TCHAR), dwCrc32);_tprintf(_T("0x%2x\n"), dwCrc32);}
改版的头文件
#ifndef _CRC32DYNAMIC_H_#define _CRC32DYNAMIC_H_/// original url form : http://www.codeproject.com/Articles/1671/CRC32-Generating-a-checksum-for-a-file/// modify by LostSpeedclass CCrc32Dynamic{public:CCrc32Dynamic();virtual ~CCrc32Dynamic();void Init(void);void Free(void);DWORD BufferCrc32(BYTE * lpcBuffer, size_t nLenBuffer, DWORD &dwCrc32);protected:inline void CalcCrc32(const BYTE byte, DWORD &dwCrc32) const;DWORD *m_pdwCrc32Table;};BOOL BufferCrc32(BYTE * lpcBuffer, size_t nLenBuffer, DWORD &dwCrc32);#endif
改版的实现文件
#include "stdafx.h"#include <windows.h>#include <tchar.h>#include <string>#include "Crc32Dynamic.h"//***********************************************CCrc32Dynamic::CCrc32Dynamic() : m_pdwCrc32Table(NULL){Init();}//***********************************************CCrc32Dynamic::~CCrc32Dynamic(){Free();}//***********************************************void CCrc32Dynamic::Init(void){// This is the official polynomial used by CRC32 in PKZip.// Often times the polynomial shown reversed as 0x04C11DB7.DWORD dwPolynomial = 0xEDB88320;int i, j;Free();m_pdwCrc32Table = new DWORD[256];DWORD dwCrc;for(i = 0; i < 256; i++){dwCrc = i;for(j = 8; j > 0; j--){if(dwCrc & 1)dwCrc = (dwCrc >> 1) ^ dwPolynomial;elsedwCrc >>= 1;}m_pdwCrc32Table[i] = dwCrc;}}//***********************************************void CCrc32Dynamic::Free(void){if(NULL != m_pdwCrc32Table){delete m_pdwCrc32Table;m_pdwCrc32Table = NULL;}}//***********************************************inline void CCrc32Dynamic::CalcCrc32(const BYTE byte, DWORD &dwCrc32) const{dwCrc32 = ((dwCrc32) >> 8) ^ m_pdwCrc32Table[(byte) ^ ((dwCrc32) & 0x000000FF)];}DWORD CCrc32Dynamic::BufferCrc32(BYTE * lpcBuffer, size_t nLenBuffer, DWORD &dwCrc32){_ASSERTE(lpcBuffer);DWORDdwErrorCode=NO_ERROR;size_tnCrcPos=0;dwCrc32 = 0xFFFFFFFF;try{// Is the table initialized?if(NULL == m_pdwCrc32Table)throw 0;while(nCrcPos < nLenBuffer){CalcCrc32(*(lpcBuffer + nCrcPos++), dwCrc32);}}catch(...){// An unknown exception happened, or the table isn't initializeddwErrorCode = ERROR_CRC;}dwCrc32 = ~dwCrc32;return dwErrorCode;}BOOL BufferCrc32(BYTE * lpcBuffer, size_t nLenBuffer, DWORD &dwCrc32){DWORDdwRc=0;CCrc32Dynamiccrc32;dwRc = crc32.BufferCrc32(lpcBuffer, nLenBuffer, dwCrc32);if(ERROR_CRC == dwRc){dwCrc32 = -1;}return (ERROR_CRC == dwRc) ? FALSE : TRUE;}
<2012_0812>
从网上下了一个CRC32的计算器, 看到同一个串计算出的CRC32和我做的这个实验不同.
而且我JAVA同事算出的CRC32和网上下的工具算出的相同...
有空查一下.
<2012_0825>
查到原因了, CRC32初始表和正确的CRC32初始表不一样.
正确的CRC32初始表参考 http://www.codeproject.com/Articles/1444/CRC_32, 初始化表的操作差很多.
还存在编码问题, 在Vs2008工程(我默认的工程设置是Unicode)中输入固定的字符, 比如: _T("1"), 在文件中, 读出来是0x31, 数量是1. 但是在工程中, 读出来是0x31, 0x00, 数量是2.
需要再查一下.
<2012_0826>
在CRC32之前, 将宽字符转成Ansi格式, 算出的CRC32值和网上找到的程序算出的CRC32值相同.
http://www.codeproject.com/Tips/128870/Useful-function-for-conversion-between-MBCS-and-WC
现在看看CRC16怎么算. 也想写个工具来算CRC16和CRC32, 支持文件方式和手工输入字符串.
CodeProject上有个计算各种HASH的Demo, 是计算文件HASH.
http://www.codeproject.com/Articles/3945/ReHash-A-console-based-hash-calculator
这个Demo中的算法以前用过, 只是单独搬了SHA1或MD5.
如果将这个Demo中的HASH类改改, 应该可以做一个带UI的通用HASH计算工具. 比网上找到的现有HASH工具要强大.
CHashManager算出的CRC32和网上下载的CRC32计算器结果相同.
先验证CRC16的结果正确性, 从网上找了2个CRC16计算器, 算出的结果和这个CHashManager算出的结果都不同, 倒...
sourceforge上有个开源工程, http://sourceforge.net/projects/fsumfe/, 支持96种HASH算法, 强大~
从这个工程可以得知, CRC16和CRC32都有多种算法.
CRC16包括: crc16, crc16_ccitt, crc16_ibm, crc16_x25, crc16_xmodem, crc16_zmodem
CRC32包括:crc32, crc32_bzip2, crc32_jamcrc, crc32_mpeg2
但是CHashManager算出的CRC16和fsumfe都不同...
看了algo目录中的crc16*.d文件, 看到不同的CRC16算法的不同, 初步看是CRC参考表不同, CRC算法不同.
而CHashManager算出的啥也不是~~, CRC初始表是fsumfe中定义的crc16, 但是CRC初值不同.
*uCrc16 = (*uCrc16 >> 8) ^ crc16tab[(*uCrc16 ^ *pBuffer++) & 0xFF]; ///<CHashManager
tmp = (tmp >>> 8 ) ^ crctab[(tmp ^ input[i]) & 0xFF];///< fsumfe
CRC16算法差不多, 不过, 改过来, CHashManager算出的结果也不对. 对CHashManager彻底失去兴趣...
现在可以考虑将fsumfe中的HASH算法移植成C++实现, 封装一些HASH算法组件.
这样, 在算HASH校验和时, 就可以选择MD5, SHA1, 累加和,异或和之外的多种HASH算法.
fsumfe是用D语言写的么??, 还好, 看起来和C差不多, 基本能看懂.
.d文件的资料: Source code written in the D programming language; similar to C++, but also influenced by C#, Java, and Eiffel; can be opened and edited in a text editor, but requires a D compiler to be compiled into an executable program..d
- experiment : convert a string to crc32
- experiment: convert dll to exe
- convert a string to XmlElement
- convert List<String> to a String
- How to convert a String to DateTime
- Convert a String to a Number
- Convert a string to an enum
- Read/convert an InputStream to a String
- Python convert a list to String
- convert a hexadecimal string to a byte string
- 字符串转换为数字:String:convert a string to int
- Implement atoi to convert a string to an integer.
- Swift: How to convert a String to UInt8 array?
- Implement atoi to convert a string to an integer.
- Convert a byte array to a Hex string
- convert a byte array to a hexadecimal string
- experiment : ip convert to DWORD value on nt driver
- Convert a String In C++ To Upper or Lower Case
- VC程序在win7系统上运行,自动获取管理员权限 .
- Qt关闭程序简单分析
- linux学习笔记——vi
- 大数据量,海量数据 处理方法总结
- 创建和读写文件的一些简单方法
- experiment : convert a string to crc32
- Google C++编程风格指南(非常有用)
- poj1125 - Stockbroker Grapevine
- 字符驱动设计----mini2440LED驱动设计之路
- Android上dip、dp、px、sp等单位说明
- Linux设备模型(中)之上层容器 (转)
- 常见设计模式之【适配器模式】
- windows下的dll文件和linux下的.so文件
- maven 配置