macOS hash 函数封装
头文件 Hash.h
#ifndef Hash_h
#define Hash_h
#include <stdint.h>
#include <vector>
class Hash final {
public:
enum struct Algorithm {
Md5,
Sha1,
};
public:
typedef std::vector<uint8_t> Data;
public:
static Data md5(const Data &data);
static Data sha1(const Data &data);
public:
~Hash();
explicit Hash(Algorithm alg);
Hash(Hash &&hash) noexcept;
Hash &operator=(Hash &&hash) noexcept;
void update(const Data &data);
Data final();
private:
struct HashImpl *_impl = nullptr;
};
#endif /* Hash_h */
实现文件 Hash.cpp
#include "Hash.h"
#include <CommonCrypto/CommonDigest.h>
#include <assert.h>
struct HashImpl {
public:
virtual ~HashImpl() = default;
virtual void update(const Hash::Data &data) = 0;
virtual Hash::Data final() = 0;
};
class Md5Impl : public HashImpl {
public:
Md5Impl()
{
CC_MD5_Init(&_ctx);
}
void update(const Hash::Data &data) override
{
CC_MD5_Update(&_ctx, data.data(), static_cast<CC_LONG>(data.size()));
}
Hash::Data final() override
{
unsigned char md[CC_MD5_DIGEST_LENGTH];
CC_MD5_Final(md, &_ctx);
return Hash::Data(std::cbegin(md), std::cend(md));
}
private:
CC_MD5_CTX _ctx;
};
class Sha1Impl : public HashImpl {
public:
Sha1Impl()
{
CC_SHA1_Init(&_ctx);
}
void update(const Hash::Data &data) override
{
CC_SHA1_Update(&_ctx, data.data(), static_cast<CC_LONG>(data.size()));
}
Hash::Data final() override
{
unsigned char md[CC_SHA1_DIGEST_LENGTH];
CC_SHA1_Final(md, &_ctx);
return Hash::Data(std::cbegin(md), std::cend(md));
}
private:
CC_SHA1_CTX _ctx;
};
#pragma mark -
Hash::~Hash()
{
delete _impl;
}
Hash::Hash(Algorithm alg)
{
switch (alg) {
case Algorithm::Md5:
_impl = new Md5Impl();
break;
case Algorithm::Sha1:
_impl = new Sha1Impl();
break;
}
}
Hash::Hash(Hash &&hash) noexcept : _impl(hash._impl)
{
hash._impl = nullptr;
}
Hash &Hash::operator=(Hash &&hash) noexcept
{
assert(&hash != this);
delete _impl;
_impl = hash._impl;
hash._impl = nullptr;
return *this;
}
void Hash::update(const Data &data)
{
_impl->update(data);
}
Hash::Data Hash::final()
{
return _impl->final();
}
#pragma mark -
Hash::Data Hash::md5(const Data &data)
{
Hash md5(Algorithm::Md5);
md5.update(data);
return md5.final();
}
Hash::Data Hash::sha1(const Data &data)
{
Hash sha1(Algorithm::Sha1);
sha1.update(data);
return sha1.final();
}
示例
#include <string>
#include "Hash.h"
int main()
{
std::string str = "hello, world";
Hash::Data data(str.cbegin(), str.cend());
auto md5 = Hash::md5(data);
// ...
auto sha1 = Hash::sha1(data);
// ...
}