사용자 도구

사이트 도구


kb:adler32hashing

Adler32 Hashing

Crc32Hashing과 마찬가지로 빠른 속도를 염두에 둔 메세지 다이제스트용 해쉬 알고리즘. 누가 더 빠른지는 잘 모르겠다. 테스트해봐야 하나…

C++ Implementation

헤더는 알아서…

Adler32Module.h
//////////////////////////////////////////////////////////////////////////////
/// \file Adler32Module.h
/// \author excel96
/// \date 2004.8.18
//////////////////////////////////////////////////////////////////////////////
 
#ifndef __ADLER32MODULE_H__
#define __ADLER32MODULE_H__
 
//////////////////////////////////////////////////////////////////////////////
/// \class Adler32Module
/// \brief 
//////////////////////////////////////////////////////////////////////////////
 
class Adler32Module
{
private:
    unsigned int m_Hash; ///< 해쉬값
 
 
public:
    /// \brief 기본 생성자
    Adler32Module() { reset(); }
 
    /// \brief 문자열을 요약
    Adler32Module(unsigned char* str) { reset(); update(str, (unsigned int)strlen((const char*)str)); }
 
    /// \brief 문자열을 요약
    Adler32Module(const std::string& text) { reset(); update(text); }
 
    /// \brief 파일의 내용을 요약
    Adler32Module(FILE* file) { reset(); update(file); }
 
    /// \brief 스트림의 내용을 요약
    Adler32Module(std::istream& stream) { reset(); update(stream); }
 
    /// \brief 파일 스트림의 내용을 요약
    Adler32Module(std::ifstream& stream) { reset(); update(stream); }
 
    /// \brief 소멸자
    virtual ~Adler32Module() {}
 
 
public:
    // 바이트 버퍼를 요약
    unsigned int update(const unsigned char* buffer, unsigned int len) 
    {
        if (!len || !buffer) return 0;
 
        unsigned int s1 = m_Hash & 0xFFFF;
        unsigned int s2 = m_Hash >> 16;
        unsigned int n  = len;
 
        while (n > 0) 
        {
            // 5552 is the largest n such that
            // 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1
            int k = (n < 5552 ? n : 5552); 
            n -= k;
 
            // Modern processors will NOT benefit from 
            // coded loop optimisation techniques (unrolling)!
            while (k--) 
            {
                s1 += *buffer++; 
                s2 += s1;
            } 
 
            s1 %= 65521; // 65521 is the largest prime smaller than 65536
            s2 %= 65521;
        }
 
        return m_Hash = (s2 << 16) | s1;
    }
 
    /// \brief 문자열을 요약
    void update(const std::string& text) 
    {
        update((unsigned char*)text.c_str(), (unsigned int)text.size());
    }
 
    /// \brief 스트림의 내용을 요약
    void update(std::istream& stream) 
    {
        unsigned char buffer[1024];
        while (stream.good())
        {
            // note that return value of read is unusable.
            stream.read((char*)(&buffer[0]), 1024); 
            update(buffer, stream.gcount());
        }
    }
 
    /// \brief 파일 스트림의 내용을 요약
    void update(std::ifstream& stream)
    {
        unsigned char buffer[1024];
        while (stream.good())
        {
            // note that return value of read is unusable.
            stream.read((char*)(&buffer[0]), 1024); 
            update(buffer, stream.gcount());
        }
    }
 
    /// \brief 파일의 내용을 요약
    void update(FILE* file) 
    {
        unsigned char buffer[1024];
        size_t len = 0;
        while ((len = ::fread(buffer, 1, 1024, file)) > 0)
        {
            update(buffer, (unsigned int)len);
        }
 
        ::fclose(file);
    }
 
 
public:
    // 해쉬값을 초기화한다.
    void reset() { m_Hash = 1; } 
 
    // 해쉬값을 반환한다.
    unsigned int digest() const { return m_Hash; }
};
 
#endif //__ADLER32MODULE_H__

kb/adler32hashing.txt · 마지막으로 수정됨: 2014/11/10 19:50 (바깥 편집)