#ifndef HGL_UTIL_HASH_INCLUDE #define HGL_UTIL_HASH_INCLUDE #include namespace hgl { namespace util { /** * Hash算法枚举 */ enum class HASH ///Hash算法枚举 { Adler32, ///<一种较CRC32更为安全的快速HASH算法 CRC32, ///<最快速的HASH算法,但最不安全,仅用于低安全性的简单验证 MD4, ///<较MD5在安全性下稍弱。但仍未被攻破,且较MD5更快 MD5, ///<最常用的HASH算法 SHA1, ///<较MD5更为安全,但计算较慢 SHA1LE, /// struct HashCode { unsigned char code[SIZE]; public: template using CharArray=T[(SIZE<<1)+1]; public: HashCode() { hgl_zero(code); } static constexpr int size(){return SIZE;} const unsigned char operator[](int index)const { return code[index]; } void CopyFrom(const void *ptr) { memcpy(code,ptr,SIZE); } void FromString(const char *str) { ParseHexStr(code,str,SIZE); } template void ToUpperString(T *str,const T gap_char=0) const { ToUpperHexStr(str,code,SIZE,gap_char); } template void ToLowerString(T *str,const T gap_char=0) const { ToLowerHexStr(str,code,SIZE,gap_char); } const int CompFunc(const HashCode &hash)const { const unsigned char *s=code; const unsigned char *t=hash.code; for(int i=0;i &,CompFunc) };//template struct HashCode using HashCodeCRC32 =HashCode<4> ; using HashCodeAdler32 =HashCode<4> ; using HashCodeMD5 =HashCode<16> ; using HashCodeMD4 =HashCode<16> ; using HashCodeSHA1 =HashCode<20> ; using HashCodeSHA1LE =HashCode<20> ; using HashCodeSHA256 =HashCode<32> ; using HashCodeSHA512 =HashCode<64> ; using HashCodexxH32 =HashCode<4> ; using HashCodexxH64 =HashCode<8> ; using HashCodeXXH3_64 =HashCode<8> ; using HashCodeXXH3_128 =HashCode<16> ; const int hash_code_bytes[]={4,4,16,16,20,20,32,64,4,8,16}; //hash码长度 /** * 散列值计算功能基类 */ class Hash ///散列值计算功能基类 { public: virtual ~Hash()=default; virtual void GetName(UTF8String &)const=0; ///<取得HASH算法的名称 virtual void GetName(UTF16String &)const=0; ///<取得HASH算法的名称 virtual const int GetHashBytes()const=0; ///<取得HASH码字节长度(MD4/MD5为16,SHA1为20) virtual void Init()=0; ///<初始化散列值计算 virtual void Update(const void *,uint)=0; ///<提交新的数据 virtual void Final(void *)=0; ///<结束并取得结果 template void Write(const T &data) { Update(&data,sizeof(T)); } template void Write(const T *ptr,const uint count) { Update(ptr,sizeof(T)*count); } };//class Hash template Hash *CreateHash(); ///<创建一个hash值计算类实例 #define HGL_CREATE_HASH_FUNC(name) Hash *Create##name##Hash(); \ template<> inline Hash *CreateHash(){return Create##name##Hash();} HGL_CREATE_HASH_FUNC(Adler32) HGL_CREATE_HASH_FUNC(CRC32) HGL_CREATE_HASH_FUNC(MD4) HGL_CREATE_HASH_FUNC(MD5) HGL_CREATE_HASH_FUNC(SHA1) HGL_CREATE_HASH_FUNC(SHA1LE) HGL_CREATE_HASH_FUNC(SHA256) HGL_CREATE_HASH_FUNC(SHA512) HGL_CREATE_HASH_FUNC(xxH32) HGL_CREATE_HASH_FUNC(xxH64) HGL_CREATE_HASH_FUNC(XXH3_64) HGL_CREATE_HASH_FUNC(XXH3_128) #undef HGL_CREATE_HASH_FUNC inline Hash *CreateHash(HASH ha) { RANGE_CHECK_RETURN_NULLPTR(ha) using CreateHashFunc=Hash *(*)(); const CreateHashFunc func[(size_t)HASH::RANGE_SIZE]= { CreateAdler32Hash, CreateCRC32Hash, CreateMD4Hash, CreateMD5Hash, CreateSHA1Hash, CreateSHA1LEHash, CreateSHA256Hash, CreateSHA512Hash, CreatexxH32Hash, CreatexxH64Hash, CreateXXH3_64Hash, CreateXXH3_128Hash, }; return func[(size_t)ha](); } /** * 计算一段数据的Hash值 * @param data 数据指针 * @param size 数据长度 * @param ha hash算法 * @param hash_code 计算后的hash值存放处 * @return 是否计算成功 */ template bool CountHash(const void *data,int size,void *hash_code) { if(!data||size<=0||!hash_code)return(false); Hash *h=CreateHash(); if(!h)return(false); h->Init(); h->Update(data,size); h->Final(hash_code); delete h; return(true); } /** * 计算一段数据的Hash值 * @param data 数据指针 * @param size 数据长度 * @param ha hash算法 * @param hash_code 计算后的hash值存放处 * @return 是否计算成功 */ inline bool CountHash(const void *data,int size,HASH ha,void *hash_code) { RANGE_CHECK_RETURN_FALSE(ha) if(!data||size<=0||!hash_code)return(false); using CountHashFunc=bool (*)(const void *,int size,void *); const CountHashFunc func[(size_t)HASH::RANGE_SIZE]= { CountHash, CountHash, CountHash, CountHash, CountHash, CountHash, CountHash, CountHash, CountHash, CountHash, CountHash, CountHash }; return func[(size_t)ha](data,size,hash_code); } /** * 计算一段数据的Hash值 * @param data 数据指针 * @param size 数据长度 * @param ha hash算法 * @param hash_str 计算后的hash值存放处 * @param litter 小写字母 * @return 是否计算成功 */ template bool CountHashStr(const void *data,int size,UTF8String &hash_str,bool litter=true) { if(!data||size<=0)return(false); Hash *h=CreateHash(); if(!h)return(false); const int hash_bytes=hash_code_bytes[(size_t)ha]; uint8 *hash_code=new uint8[hash_bytes]; char *hash_code_str=new char[1+(hash_bytes<<1)]; h->Init(); h->Update(data,size); h->Final(hash_code); delete h; DataToHexStr(hash_code_str,hash_code,hash_bytes,litter?LowerHexChar:UpperHexChar); hash_str.SetInstance(hash_code_str,hash_bytes<<1); delete[] hash_code; return(true); } /** * 计算一段数据的Hash值 * @param data 数据指针 * @param size 数据长度 * @param ha hash算法 * @param hash_str 计算后的hash值存放处 * @param litter 小写字母 * @return 是否计算成功 */ inline bool CountHash(const void *data,int size,HASH ha,UTF8String &hash_str,bool litter=true) { RANGE_CHECK_RETURN_FALSE(ha) if(!data||size<=0)return(false); using CountHashFunc=bool (*)(const void *,int size,UTF8String &,bool); const CountHashFunc func[(size_t)HASH::RANGE_SIZE]= { CountHashStr, CountHashStr, CountHashStr, CountHashStr, CountHashStr, CountHashStr, CountHashStr, CountHashStr, CountHashStr, CountHashStr, CountHashStr, CountHashStr }; return func[(size_t)ha](data,size,hash_str,litter); } #define HGL_COUNT_HASH_FUNC(name) inline bool Count##name(const void *data, int size, HashCode##name &hc) { return CountHash(data, size, &hc); } \ inline bool Count##name(const void *data, int size, UTF8String &hash_str, bool litter = true) { return CountHashStr(data, size, hash_str, litter); } \ inline bool Count##name(const UTF8String &str, UTF8String &hash_str, bool litter = true) { return CountHashStr(str.c_str(), str.Length(), hash_str, litter); } HGL_COUNT_HASH_FUNC(Adler32) HGL_COUNT_HASH_FUNC(CRC32) HGL_COUNT_HASH_FUNC(MD4) HGL_COUNT_HASH_FUNC(MD5) HGL_COUNT_HASH_FUNC(SHA1) HGL_COUNT_HASH_FUNC(SHA1LE) HGL_COUNT_HASH_FUNC(SHA256) HGL_COUNT_HASH_FUNC(SHA512) HGL_COUNT_HASH_FUNC(xxH32) HGL_COUNT_HASH_FUNC(xxH64) HGL_COUNT_HASH_FUNC(XXH3_64) HGL_COUNT_HASH_FUNC(XXH3_128) #undef HGL_COUNT_HASH_FUNC /** * 取得一个文件的hash值 * @param filename 文件名 * @param ha hash算法 * @param hash_code 计算后的hash存放处 * @return 是否计算成功 */ bool GetFileHash(const OSString &filename,HASH ha,void *hash_code); /** * 取得一个文件的hash值 * @param filename 文件名 * @param ha hash算法 * @param hash_str 计算后的hash值存放处 * @param litter 小写字母 * @return 是否计算成功 */ bool GetFileHash(const OSString &filename,HASH ha,UTF8String &hash_str,bool litter=true); }//namespace util }//namespace hgl #endif//HGL_UTIL_HASH_INCLUDE