This commit is contained in:
2025-05-15 16:54:43 +08:00
parent d8dba2f70e
commit e444af237e
3 changed files with 248 additions and 30 deletions

View File

@@ -17,24 +17,67 @@ namespace hash_lib {
* The byte length of the block
*/
virtual int blockSize() = 0;
/**
* Update the hash with data
* @param data Data to be hashed
* @param len Length of the data
* @return this
*/
virtual Hash* update(const uint8_t* data, size_t len) = 0;
/**
* Update the hash with data
* @param data Data to be hashed
* @return this
*/
template<size_t T>
Hash* update(const uint8_t(&data)[T]) {
return this->update(data, T);
}
Hash* update(const std::string& data);
Hash* update(const std::vector<uint8_t>& data);
/**
* Update the hash with data from a file
* @param f File pointer
* @return this
*/
Hash* update(FILE* f);
/**
* Reset the hash
* @return this
*/
virtual Hash* reset() = 0;
/**
* Finish the hash and return the result
* @param data Buffer to store the result
* @param len Length of the buffer
* @return this
*/
virtual Hash* finish(uint8_t* data, size_t len) = 0;
/**
* Finish the hash and return the result
* @param data Buffer to store the result
* @return this
*/
template<size_t T>
Hash* finish(uint8_t(&data)[T]) {
return this->finish(data, T);
}
Hash* finish(std::string& data);
Hash* finish(std::vector<uint8_t>& data);
/**
* Finish the hash and return the result
* @return The hash result
*/
std::vector<uint8_t> digest();
/**
* Reset the hash and clean the buffer
* @return this
*/
virtual void clean() = 0;
/**
* Finish the hash and return the result in hex format
* @return The hash result in hex format
*/
std::string hexDigest();
};
class SHA512: public Hash {
@@ -126,6 +169,28 @@ namespace hash_lib {
bool _finished = false;
size_t hashBlocks(const uint8_t* m, size_t pos, size_t len);
};
class MD5: public Hash {
public:
MD5();
virtual int digestLength() override;
int blockSize() override;
Hash* update(const uint8_t* data, size_t len) override;
using Hash::update;
Hash* reset() override;
Hash* finish(uint8_t* data, size_t len) override;
using Hash::finish;
void clean() override;
protected:
uint32_t state[4];
virtual void _initState();
private:
uint32_t _temp[64];
uint8_t _buffer[128];
size_t _bufferLength = 0;
size_t _bytesHashed = 0;
bool _finished = false;
size_t hashBlocks(const uint8_t* m, size_t pos, size_t len);
};
template<class H>
class HMAC: public Hash {
public:
@@ -190,61 +255,61 @@ namespace hash_lib {
std::vector<uint8_t> _pad;
bool _finished = false;
};
template<class H>
std::vector<uint8_t> hash(const uint8_t* data, size_t len) {
H h;
template<class H, typename ... Args>
std::vector<uint8_t> hash(const uint8_t* data, size_t len, Args... args) {
H h(args...);
h.update(data, len);
return h.digest();
}
template<class H>
std::vector<uint8_t> hash(const std::string& data) {
H h;
template<class H, typename ... Args>
std::vector<uint8_t> hash(const std::string& data, Args... args) {
H h(args...);
h.update(data);
return h.digest();
}
template<class H>
std::vector<uint8_t> hash(const std::vector<uint8_t>& data) {
H h;
template<class H, typename ... Args>
std::vector<uint8_t> hash(const std::vector<uint8_t>& data, Args... args) {
H h(args...);
h.update(data);
return h.digest();
}
template<class H, size_t T>
std::vector<uint8_t> hash(const uint8_t(&data)[T]) {
H h;
template<class H, size_t T, typename ... Args>
std::vector<uint8_t> hash(const uint8_t(&data)[T], Args... args) {
H h(args...);
h.update(data);
return h.digest();
}
template<class H>
std::string hashHex(const uint8_t* data, size_t len) {
H h;
template<class H, typename ... Args>
std::string hashHex(const uint8_t* data, size_t len, Args... args) {
H h(args...);
h.update(data, len);
return h.hexDigest();
}
template<class H>
std::string hashHex(const std::string& data) {
H h;
template<class H, typename ... Args>
std::string hashHex(const std::string& data, Args... args) {
H h(args...);
h.update(data);
return h.hexDigest();
}
template<class H>
std::string hashHex(const std::vector<uint8_t>& data) {
H h;
template<class H, typename ... Args>
std::string hashHex(const std::vector<uint8_t>& data, Args... args) {
H h(args...);
h.update(data);
return h.hexDigest();
}
template<class H, size_t T>
std::string hashHex(const uint8_t(&data)[T]) {
H h;
template<class H, size_t T, typename ... Args>
std::string hashHex(const uint8_t(&data)[T], Args... args) {
H h(args...);
h.update(data);
return h.hexDigest();
}
template<class H>
std::vector<uint8_t> hashFile(const std::string& filePath) {
template<class H, typename ... Args>
std::vector<uint8_t> hashFile(const std::string& filePath, Args... args) {
FILE* f = fileop::fopen(filePath.c_str(), "rb");
if (!f) {
return {};
}
H h;
H h(args...);
h.update(f);
if (ferror(f)) {
fileop::fclose(f);
@@ -253,13 +318,13 @@ namespace hash_lib {
fileop::fclose(f);
return h.digest();
}
template<class H>
std::string hashHexFile(const std::string& filePath) {
template<class H, typename ... Args>
std::string hashHexFile(const std::string& filePath, Args... args) {
FILE* f = fileop::fopen(filePath.c_str(), "rb");
if (!f) {
return "";
}
H h;
H h(args...);
h.update(f);
if (ferror(f)) {
fileop::fclose(f);