Search code examples
c++hexpipelinecrypto++

HexDecoder output empty


I'm having a bit of an issue with cryptopp562 (on Debian for what it matters) I have a hex string and am trying to convert it to a decimal int. I'm using the HexDecoder in cryptopp (since I'm already using cryptopp for other things in the project). Since I don't know of a way to go straight from a hex string to a decimal int in one step, I have an intermediate step of decimal string. So it goes

Hex string > Decimal string > Decimal int

However my pipeline appears to be incorrect, but I can't for the life of me figure out why. I'm not even getting the hex string to decimal string bit right, so my decimal int just constantly reads 0. I've used Base64Encoder (and Decoder), and ZlibCompressor (and Decompressor) in the past with no problem, so this is sort of a little embarrassing because it should just be more of the same.

std::string RecoveredDecimalString;
std::string RecoveredHex = "39"; //Hex, so would be 63 in decimal
CryptoPP::StringSource (RecoveredHex, true /*PumpAll*/,
    new CryptoPP::HexDecoder(
        new CryptoPP::StringSink(RecoveredDecimalString) /*StringSink*/
    )/*HexDecoder*/
);/*StringSource*/

But like I say, after running this, RecoveredDecimalString.empty() returns true. At first I thought it was because I'd missed off the pump all parameter, but adding that made no difference, still nothing's flowing.

A similar question was asked (and answered) a year ago. The answer came back as "read the cryptoPP wiki", but I can't see how my code is different from what's on their wiki.

What have I forgotten? I know it's going to be something very small.


Solution

  • std::string RecoveredDecimalString;
    std::string RecoveredHex = "39"; //Hex, so would be 63 in decimal
    CryptoPP::StringSource (RecoveredHex, true /*PumpAll*/,
        new CryptoPP::HexDecoder(
            new CryptoPP::StringSink(RecoveredDecimalString) /*StringSink*/
        )/*HexDecoder*/
    );/*StringSource*/
    

    Name your StringSource. In the update to your code, notice the StringSource was named ss.

    std::string decoded;
    std::string encoded = "39"; //Hex, so would be 63 in decimal
    CryptoPP::StringSource ss(encoded, true /*PumpAll*/,
        new CryptoPP::HexDecoder(
            new CryptoPP::StringSink(decoded) /*StringSink*/
        )/*HexDecoder*/
    );/*StringSource*/
    

    Some versions of GCC have trouble with anonymous declarations. I tracked it down some time ago to StringSink destructors running too soon (before the data was pumped). I wanted to file a GCC bug report, but I could never get it reduced to a minimal case.

    You could also perform:

    std::string decoded;
    std::string encoded = "39"; //Hex, so would be 63 in decimal
    
    CryptoPP::HexDecoder decoder(new CryptoPP::StringSink(decoded));
    decoder.Put(encoded.data(), encoded.size());
    decoder.MessageEnd();