VoidBunny
VoidBunny

Reputation: 67

How to convert a binary byte into a printable numeric value?

I have to convert the CRYPTO++ AES ciphertext of 128 bits into a pribtable numerical string.

I am currently using the following code to do the casting, but bitset is too slow for my case. Does anyone know any efficient way of doing this?

string output = "";
for (std::size_t i = 0; i < 16; ++ i) {
    output += bitset<8>(ciphertext[i]).to_string();
} 

How to convert a binary byte into a printable numeric value? Thanks a lot!

Upvotes: 1

Views: 130

Answers (3)

bames53
bames53

Reputation: 88155

There are plenty of clever methods to compute a binary string from a number, but it doesn't really matter; Whatever method you use, you can use that method to fill up a table once:

std::string bytes[256];

for (unsigned char c = 0; c<=255; ++c) {
  bytes[c] = bitset<8>(c).to_string();
}

And then bytes[c] will give you the string for a particular byte.


In your post you show four lines of code. Below is what those four lines of code would change to using the above precomputed strings:

string output = "";
for (std::size_t i = 0; i < 16; ++ i) {
    output += bytes[ciphertext[i]];
} 

Also, your code likely involves some allocations during your loop. The best way to avoid those depends entirely on how you use the output string, but at the minimum output.reserve(16*8) can't hurt.

Upvotes: 2

jww
jww

Reputation: 102235

string output = "";
for (std::size_t i = 0; i < 16; ++ i) {
    output += bitset<8>(ciphertext[i]).to_string();
} 

There's also the Crypto++ source/sink method if you are itnerested:

string output;
ArraySource as(ciphertext, sizeof(ciphertext),
    true /*pump*/,
    new HexEncoder(
        new StringSink(output)
    ) // HexEncoder
); // ArraySource

Upvotes: 0

zwol
zwol

Reputation: 140559

I would do

char ct_b[16];
char ct_h[33]; // 2 hex digits per byte + NUL
snprintf(ct_h, 33,
         "%02x%02x%02x%02x%02x%02x%02x%02x"
         "%02x%02x%02x%02x%02x%02x%02x%02x",
         ct_h[ 0], ct_h[ 1], ct_h[ 2], ct_h[ 3],
         ct_h[ 4], ct_h[ 5], ct_h[ 6], ct_h[ 7],
         ct_h[ 8], ct_h[ 9], ct_h[10], ct_h[11],
         ct_h[12], ct_h[13], ct_h[14], ct_h[15]);

This will certainly be faster than what you have, at the expense of a good bit more repetition. It does produce hexadecimal rather than binary, but it's very likely that hex is what you really want.

(In case you haven't seen string constant concatenation before: The absence of a comma after the first half of the string constant is intentional.)

(Please tell me you aren't using ECB.)

Upvotes: 0

Related Questions