This is a simple question I think. I'm messing around with the Crypto++ lib and a sample which I found on SO. So I tried to cout the text/ASCII characters (instead of hex) at the "Dump cipher text" part.
This part (original):
//
// Dump Cipher Text
//
std::cout << "Cipher Text (" << ciphertext.size() << " bytes)" << std::endl;
for( int i = 0; i < ciphertext.size(); i++ ) {
std::cout << "0x" << std::hex << (0xFF & static_cast<byte>(ciphertext[i])) << " ";
}
std::cout << std::endl << std::endl;
And I've noticed something odd... the ciphertext.size() returns a different number of bytes after I tried to do this:
My edited part:
//
// Dump Cipher Text
//
std::cout << "Cipher Text (" << ciphertext.size() << " bytes)" << std::endl; // returns 16 bytes.
int num = ciphertext.size(); // num returns 16 here
for (int i = 0; i < ciphertext.size(); i++) {
std::cout << "0x" << std::hex << (0xFF & static_cast<byte>(ciphertext[i])) << " ";
}
std::cout << std::endl << std::endl;
std::cout << "Ciphertext size: " << ciphertext.size() << std::endl; // now it's 10 bytes?
std::cout << "num: " << num; // returns 10 bytes?! what the hell...
std::cout << std::endl << std::endl;
So I bumped into this because I tried to print the ASCII characters instead of the hex bytes, and it worked but I just can't understand why...
Because this:
std::cout << "To Text: ";
for (int x = 0; x < ciphertext.size(); x++)
{
std::cout << ciphertext[x];
}
Prints all the ASCII chars (instead of hex), but... since ciphertext.size() returns 10, it shouldn't print all the chars (because it was first defined as 16 instead of 10) but yet, it does print them all perfectly.... I'm really confused here. How can a variable redefine itself EVEN if I placed/copied it in a int to make sure it doesn't get changed?
std::hex changes the base used to represent the numbers to 16 (hex). All the numbers inserted into std::cout after std::cout << std::hex are represented in base 16.
ciphertext.size() still returns 16 but, because of the std::hex previously sent to output, it is displayed in base 16 and its hex representation is, of course, 10.
Try this:
std::cout << std::dec << "Ciphertext size: " << ciphertext.size() << std::endl;
It sets 10 as base for numbers representation again and makes the value returned by ciphertext.size() to be displayed as 16.
Encryption output is binary bytes with values ranging from 0 to 255. ASCII printable characters range from 32 to 127. Perhaps you can see the problem at this point.
Not all byte values are representable in ASCII, not even extended ASCII or unicode, that is why Hexadecimal and Base64 are used for encrypted output.
See ASCII character values.
Related
int main()
{
char B[76]={0};
ifstream infile;
infile.open("tworecords.dat", ios::binary);
infile.read(reinterpret_cast<char*>(B), sizeof (B));
cout << "Array B in hex" << endl;
for (int i = 0; i < 76; i++)
{
cout << hex << B[i] << " " << endl;;
}
return 0;
}
right now it reads the data correctly, but prints out the values as ASCII symbols. I would like to output the actual hex values in the file.
example:
01
3D
76
D6
etc.
Cast it to integer:
cout << hex << static_cast<int>(B[i]) << " " << endl;
Or alternatively, if you don't want to cast, just add 0:
cout << hex << B[i]+0 << " " << endl;
However you probably also want to make sure that for values below 16, a leading 0 is printed (e.g. for the newline character 0A, not just A):
cout << setfill('0') << setw(2) << hex << B[i]+0 << " " << endl;
You simply cast the number to an integer:
cout << hex << (int)B[i] << " " << endl;
the <iostream> library (actually, all stream libraries) output ascii values for char types.
How can I express the value of an integer using decimal, octal or hexadecimal representation?
(I would prefer only iostream usage)
Assuming you just want to see them, for your own reference. Though storing them in a variable is "just a shot away".
#include <iostream>
using namespace std;
int main () {
int n;
n=70;
cout << hex << n << endl;
cout << dec << n << endl;
cout << oct << n << endl;
return 0;
}
By "decimal integer" I hope you mean a string that uses decimal to represent an integer. Integer types, like int, do not have a base. Or if you insist that they must have a base because of their internal representation then the base is always 2. String representations of integers, now those have a base.
std::istringstream iss(std::string("123"));
int i;
if (iss >> i) {
std::cout << "read a decimal integer!\n";
std::cout << "here it is in decimal: " << i << "\n";
std::cout << "here it is in hex: " << std::hex << i << "\n";
std::cout << "here it is in octal: " << std::oct << i << "\n";
}
Not sure how else to put that, but I'll start off with a code snippet and output:
uint32_t expires;
cout << "Expiration bytes: " << setfill('0') << hex
<< setw(2) << (unsigned short)rec[keyLen+4]
<< setw(2) << (unsigned short)rec[keyLen+5]
<< setw(2) << (unsigned short)rec[keyLen+6]
<< setw(2) << (unsigned short)rec[keyLen+7] << endl;
expires = ntohl(*(uint32_t*)&rec[keyLen+4]);
cout << "Expiration: " << (long)expires << endl;
cout << "Hex: " << hex << expires << endl;
Outputs:
Expiration bytes: 00000258
Expiration: 258
Hex: 258
I can confirm from other parts of the program that examining and outputting the hex representation of bytes works as expected, and that those are indeed the bytes in the byte stream (sent from another application).
Now, I would be able to understand a bit better if expiration just held some nonsense, because that would mean there's some egregious error (probably involving pointers). But this... this is clearly just spitting out the hex value as if it were a decimal, and that's plain wrong.
To make matters more confusing, this works at another point in the program:
fullSize = ntohs(*(uint16_t*)&buff[0]);
With a byte value of 0x0114, fullSize will contain the value 276.
So the question is, what the heck is going on here? How is it possible for an int to be wrong?
hex is sticky, so unless you reset it, cout will continue to output things in hex.
You can reset it by issuing sending std::dec to the stream. Alternatively you could build a more advanced mechanism that would store the original state and restore it afterwords.
cout << "Expiration: " << dec << (long)expires << endl; will output decimal, otherwise the last setting (hex or dec) will still be in effect.
Since you never switch cout back to decimal output, all of your outputs are in hex, even the output of cout << "Expiration: " << (long)expires << endl;.
In C++ I need string representations of integers with leading zeroes, where the representation has 8 digits and no more than 8 digits, truncating digits on the right side if necessary. I thought I could do this using just ostringstream and iomanip.setw(), like this:
int num_1 = 3000;
ostringstream out_target;
out_target << setw(8) << setfill('0') << num_1;
cout << "field: " << out_target.str() << " vs input: " << num_1 << endl;
The output here is:
field: 00003000 vs input: 3000
Very nice! However if I try a bigger number, setw lets the output grow beyond 8 characters:
int num_2 = 2000000000;
ostringstream out_target;
out_target << setw(8) << setfill('0') << num_2;
cout << "field: " << out_target.str() << " vs input: " << num_2 << endl;
out_target.str("");
output:
field: 2000000000 vs input: 2000000000
The desired output is "20000000". There's nothing stopping me from using a second operation to take only the first 8 characters, but is field truncation truly missing from iomanip? Would the Boost formatting do what I need in one step?
I can't think of any way to truncate a numeric field like that. Perhaps it has not been implemented because it would change the value.
ostream::write() allows you to truncate a string buffer simply enough, as in this example...
int num_2 = 2000000000;
ostringstream out_target;
out_target << setw(8) << setfill('0') << num_2;
cout << "field: ";
cout.write(out_target.str().c_str(), 8);
cout << " vs input: " << num_2 << endl;
If you assume that snprintf() will write as many chars at it can (I don't think this is guaranteed),
char buf[9];
snprintf(buf, 10, "%08d", num);
buf[8] = 0;
cout << std::string(buf) << endl;
I am not sure why you want 2 billion to be the same as 20 million. It may make more sense to signal an error on truncation, like this:
if (snprintf(buf, 10, "%08d", num) > 8) {
throw std::exception("oops")
}
I'm trying to output the hex value of a char and format it in a nice way.
Required: 0x01 : value 0x1
All I can get is: 00x1 : value 0x1 // or 0x1 if i don't use iomanip
Here's the code i have, 'ch' was declared to be a unsigned char. Is there any other way to do it other than checking the value and manually add an '0'??
cout << showbase;
cout << hex << setw(2) << setfill('0') << (int) ch;
Edit:
I found one solution online:
cout << internal << setw(4) << setfill('0') << hex << (int) ch
std::cout << "0x" << std::noshowbase << std::hex << std::setw(2) << std::setfill('0') << (int)ch;
Since setw pads out to the left of the overall printed number (after showbase is applied), showbase isn't usable in your case. Instead, manually print out the base as shown above.
In one on my projects I did this:
ostream &operator<<(ostream &stream, byte value)
{
stream << "0x" << hex << (int)value;
return stream;
}
I surchaged the operator<< for stream output, and anything that was a byte was shown in hexadecimal. byte is a typedef for unsigned char.