Edit: I just reread your question (in the intend to edit it). I think you misunderstood the format SHA256 expects you to use. Instead of appending the string 00 00 00 00 00 00 00 18
(each byte hex encoded and separated by spaces) for a message length of 24 you need to append the raw bytes 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 and 0x18. They do not represent any printable characters. See below for a way to get these bytes. My example uses an integer whose byte representation happens to contain only printable characters (in ASCII).
Btw., the reason you pad to 448 bits is that you have 64 bits left in the full block size of 512 bits so you can put the big-endian encoding of the message length in there.
You can extract a single byte of num
using num>>(8*i) & 0xff
where you will get the least significant byte for i=0
and the most significant byte of an unsigned long (64bit) with i=7
. Iterating through all positions you can get each byte:
unsigned long num = 0x626967656e646961L;
//Store big endian representation in a vector:
std::vector<unsigned char> bigEndian;
for(int i=7; i>=0; i--){
bigEndian.push_back( (num>>(8*i)) & 0xff );
}
If you need it as a string you can convert it using the iterator constructor of a string:
std::string bigEndianString(bigEndian.begin(),bigEndian.end());
Complete code with test output:
#include <iostream>
#include <string>
#include <vector>
int main() {
unsigned long num = 0x626967656e646961L;
//Store big endian representation in a vector:
std::vector<unsigned char> bigEndian;
for(int i=7; i>=0; i--){
bigEndian.push_back( (num>>(8*i)) & 0xff );
}
//Convert vector to string:
std::string bigEndianString(bigEndian.begin(),bigEndian.end());
//Test correctness:
for(std::vector<unsigned char>::const_iterator it = bigEndian.begin(); it != bigEndian.end(); ++it) {
std::cout << std::hex << (int)*it << ' ';
}
std::cout << std::endl << bigEndianString << std::endl;
}