Functions:
encc - Encrypts plain text and returns "ivString::ciphertxt".
decc - Disassembles the IV and ciphertext and Decrypts 'ciphertext'.
string encc(string plain) {
    using namespace CryptoPP;
    AutoSeededRandomPool prng;
    SecByteBlock iv(AES::BLOCKSIZE);
    
    //the password
    std::string sKey = "UltraSecretKeyPhrase";
    
    // Convert "UltraSecretKeyPhrase" to SecByteBlock
    SecByteBlock key((const unsigned char*)(sKey.data()), sKey.size());
    
    // Generate IV
    prng.GenerateBlock(iv, iv.size());
    std::string cipher, recovered;
    //Try Encrypt
    try
    {
        CBC_Mode< AES >::Encryption e;
        e.SetKeyWithIV(key, key.size(), iv);
        StringSource s(plain, true,
            new StreamTransformationFilter(e,
                new StringSink(cipher)
            ) 
        ); 
    }
    catch (const Exception& e)
    {
        exit(1);
    }
    string ciphertxt, ivString;
    
    //HexEncode IV
    HexEncoder encoder(new FileSink(std::cout));
    encoder.Detach(new StringSink(ivString));
    encoder.Put(iv, iv.size());
    encoder.MessageEnd();
    //HexEncode ciphertxt
    encoder.Detach(new StringSink(ciphertxt));
    encoder.Put((const byte*)&cipher[0], cipher.size());
    encoder.MessageEnd();
    string toSend = ivString + "::" + ciphertxt;
    return toSend;
}
string decc(string toDec) {
    using namespace CryptoPP;
    std::string sKey = "UltraSecretKeyPhrase";
    SecByteBlock key((const unsigned char*)(sKey.data()), sKey.size());
    std::string recovered;
    string str1 = "::";
    size_t found = toDec.find(str1);
    //seperate iv and ciphertxt
    if (found != string::npos) {
        std::string sIv = toDec.substr(0, found);
        std::string encMessageHex = toDec.substr(found + 2);
    
        cout << endl << "IV: " << sIv << endl << "Encoded Msg: " << encMessageHex << endl;
    
        string iv, encMessage;
        HexDecoder decoder, msgDecoder;
        //Decode the IV Hex back to byte*
        decoder.Attach(new StringSink(iv));
        decoder.Put((byte*)sIv.data(), sIv.size());
        decoder.MessageEnd();
        
        //Decode the ciphertxt Hex back to byte*
        decoder.Attach(new StringSink(encMessage));
        decoder.Put((byte*)encMessageHex.data(), encMessageHex.size());
        decoder.MessageEnd();
        //Try decoding the ciphertxt
        try
        {
            CBC_Mode< AES >::Decryption d;
            d.SetKeyWithIV(key.data(), key.size(), (byte *)iv.data(), AES::BLOCKSIZE);
            StringSource s(encMessage, true,
                new StreamTransformationFilter(d,
                    new StringSink(recovered)
                )
            );
            return recovered;
        }
        catch (const Exception& e)
        {
            std::cerr << e.what() << std::endl;
             exit(1);
        }
    }
    else return NULL;
}
int main(){
    string hh = encc("this is encoded");
    cout << hh << endl;
    string gg = decc(hh);
    cout << gg << endl;
    return 0;
}