mirror of
				https://github.com/ciphervance/supercell-wx.git
				synced 2025-10-31 12:40:06 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			82 lines
		
	
	
	
		
			1.9 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			82 lines
		
	
	
	
		
			1.9 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| #include <scwx/util/digest.hpp>
 | |
| #include <scwx/util/logger.hpp>
 | |
| 
 | |
| namespace scwx
 | |
| {
 | |
| namespace util
 | |
| {
 | |
| 
 | |
| static const std::string logPrefix_ = "scwx::util::digest";
 | |
| static const auto        logger_    = scwx::util::Logger::Create(logPrefix_);
 | |
| 
 | |
| bool ComputeDigest(const EVP_MD*              mdtype,
 | |
|                    std::istream&              is,
 | |
|                    std::vector<std::uint8_t>& digest)
 | |
| {
 | |
|    int         mdsize;
 | |
|    EVP_MD_CTX* mdctx = nullptr;
 | |
| 
 | |
|    digest.clear();
 | |
| 
 | |
|    if ((mdsize = EVP_MD_get_size(mdtype)) < 1)
 | |
|    {
 | |
|       logger_->error("Invalid digest");
 | |
|       return false;
 | |
|    }
 | |
| 
 | |
|    if ((mdctx = EVP_MD_CTX_new()) == nullptr)
 | |
|    {
 | |
|       logger_->error("Error allocating a digest context");
 | |
|       return false;
 | |
|    }
 | |
| 
 | |
|    if (!EVP_DigestInit_ex(mdctx, mdtype, nullptr))
 | |
|    {
 | |
|       logger_->error("Message digest initialization failed");
 | |
|       EVP_MD_CTX_free(mdctx);
 | |
|       return false;
 | |
|    }
 | |
| 
 | |
|    is.seekg(0, std::ios_base::end);
 | |
|    const std::size_t streamSize = is.tellg();
 | |
|    is.seekg(0, std::ios_base::beg);
 | |
| 
 | |
|    std::size_t bytesRead = 0;
 | |
|    std::size_t chunkSize = 4096;
 | |
|    std::string fileData;
 | |
|    fileData.resize(chunkSize);
 | |
| 
 | |
|    while (bytesRead < streamSize)
 | |
|    {
 | |
|       const std::size_t bytesRemaining = streamSize - bytesRead;
 | |
|       const std::size_t readSize       = std::min(chunkSize, bytesRemaining);
 | |
| 
 | |
|       is.read(fileData.data(), readSize);
 | |
| 
 | |
|       if (!is.good() || !EVP_DigestUpdate(mdctx, fileData.data(), readSize))
 | |
|       {
 | |
|          logger_->error("Message digest update failed");
 | |
|          EVP_MD_CTX_free(mdctx);
 | |
|          return false;
 | |
|       }
 | |
| 
 | |
|       bytesRead += readSize;
 | |
|    }
 | |
| 
 | |
|    digest.resize(mdsize);
 | |
| 
 | |
|    if (!EVP_DigestFinal_ex(mdctx, digest.data(), nullptr))
 | |
|    {
 | |
|       logger_->error("Message digest finalization failed");
 | |
|       EVP_MD_CTX_free(mdctx);
 | |
|       digest.clear();
 | |
|       return false;
 | |
|    }
 | |
| 
 | |
|    EVP_MD_CTX_free(mdctx);
 | |
| 
 | |
|    return true;
 | |
| }
 | |
| 
 | |
| } // namespace util
 | |
| } // namespace scwx
 | 
