Base64 encoding and decoding with OpenSSL

后端 未结 8 2127
天命终不由人
天命终不由人 2020-12-07 19:22

I\'ve been trying to figure out the openssl documentation for base64 decoding and encoding. I found some code snippets below



        
8条回答
  •  死守一世寂寞
    2020-12-07 20:02

    I like mtrw's use of EVP.

    Below is my "modern C++" take on his answer without manual memory allocation (calloc). It will take a std::string but it can easily be overloaded to use raw bytes for example.

    #include 
    
    #include 
    #include 
    #include 
    
    
    auto EncodeBase64(const std::string& to_encode) -> std::string {
      /// @sa https://www.openssl.org/docs/manmaster/man3/EVP_EncodeBlock.html
    
      const auto predicted_len = 4 * ((to_encode.length() + 2) / 3);  // predict output size
    
      const auto output_buffer{std::make_unique(predicted_len + 1)};
    
      const std::vector vec_chars{to_encode.begin(), to_encode.end()};  // convert to_encode into uchar container
    
      const auto output_len = EVP_EncodeBlock(reinterpret_cast(output_buffer.get()), vec_chars.data(), static_cast(vec_chars.size()));
    
      if (predicted_len != static_cast(output_len)) {
        throw std::runtime_error("EncodeBase64 error");
      }
    
      return output_buffer.get();
    }
    
    auto DecodeBase64(const std::string& to_decode) -> std::string {
      /// @sa https://www.openssl.org/docs/manmaster/man3/EVP_DecodeBlock.html
    
      const auto predicted_len = 3 * to_decode.length() / 4;  // predict output size
    
      const auto output_buffer{std::make_unique(predicted_len + 1)};
    
      const std::vector vec_chars{to_decode.begin(), to_decode.end()};  // convert to_decode into uchar container
    
      const auto output_len = EVP_DecodeBlock(reinterpret_cast(output_buffer.get()), vec_chars.data(), static_cast(vec_chars.size()));
    
      if (predicted_len != static_cast(output_len)) {
        throw std::runtime_error("DecodeBase64 error");
      }
    
      return output_buffer.get();
    }
    

    There's probably a cleaner/better way of doing this (I'd like to get rid of reinterpret_cast). You'll also definitely want a try/catch block to deal with the potential exception.

提交回复
热议问题