I had implemented several hash functions in C++ a while back, and I was going back through them to clean them up a little In the example below (MD5), I converted the input bytes (plus appropriate padding) to an array of 16 elements to be processed by the actual hash algorithm. The FromLittleEndian function reads the number of bytes required to fill the first template value from the input (pointer to element in MessageBlock) and returns the result in the native endian format (in this case std::uint32_t).
[source lang="c++"]
typedef std::array<std::uint32_t, 16> messagechunk_type;
const messagechunk_type ProcessBlock =
{
FromLittleEndian<std::uint32_t, CharArray::value_type>(&MessageBlock[0]),
FromLittleEndian<std::uint32_t, CharArray::value_type>(&MessageBlock[4]),
FromLittleEndian<std::uint32_t, CharArray::value_type>(&MessageBlock[8]),
FromLittleEndian<std::uint32_t, CharArray::value_type>(&MessageBlock[12]),
FromLittleEndian<std::uint32_t, CharArray::value_type>(&MessageBlock[16]),
FromLittleEndian<std::uint32_t, CharArray::value_type>(&MessageBlock[20]),
FromLittleEndian<std::uint32_t, CharArray::value_type>(&MessageBlock[24]),
FromLittleEndian<std::uint32_t, CharArray::value_type>(&MessageBlock[28]),
FromLittleEndian<std::uint32_t, CharArray::value_type>(&MessageBlock[32]),
FromLittleEndian<std::uint32_t, CharArray::value_type>(&MessageBlock[36]),
FromLittleEndian<std::uint32_t, CharArray::value_type>(&MessageBlock[40]),
FromLittleEndian<std::uint32_t, CharArray::value_type>(&MessageBlock[44]),
FromLittleEndian<std::uint32_t, CharArray::value_type>(&MessageBlock[48]),
FromLittleEndian<std::uint32_t, CharArray::value_type>(&MessageBlock[52]),
FromLittleEndian<std::uint32_t, CharArray::value_type>(&MessageBlock[56]),
FromLittleEndian<std::uint32_t, CharArray::value_type>(&MessageBlock[60])
};[/source]
I haven't tested the code below to see if the result is the same, but I was more curious if the behavior is well defined by the standard. I know that the use of commas like this can produce unexpected results in other cases.
[source lang="c++"]
typedef std::array<std::uint32_t, 16> messagechunk_type;
int Index = 0;
const messagechunk_type ProcessBlock =
{
FromLittleEndian<std::uint32_t, CharArray::value_type>(&MessageBlock[Index]), //0 - Thanks Alpha_ProgDes
FromLittleEndian<std::uint32_t, CharArray::value_type>(&MessageBlock[Index += sizeof(std::uint32_t)]), //4
FromLittleEndian<std::uint32_t, CharArray::value_type>(&MessageBlock[Index += sizeof(std::uint32_t)]), //8
FromLittleEndian<std::uint32_t, CharArray::value_type>(&MessageBlock[Index += sizeof(std::uint32_t)]), //12
FromLittleEndian<std::uint32_t, CharArray::value_type>(&MessageBlock[Index += sizeof(std::uint32_t)]), //16
FromLittleEndian<std::uint32_t, CharArray::value_type>(&MessageBlock[Index += sizeof(std::uint32_t)]), //20
FromLittleEndian<std::uint32_t, CharArray::value_type>(&MessageBlock[Index += sizeof(std::uint32_t)]), //24
FromLittleEndian<std::uint32_t, CharArray::value_type>(&MessageBlock[Index += sizeof(std::uint32_t)]), //28
FromLittleEndian<std::uint32_t, CharArray::value_type>(&MessageBlock[Index += sizeof(std::uint32_t)]), //32
FromLittleEndian<std::uint32_t, CharArray::value_type>(&MessageBlock[Index += sizeof(std::uint32_t)]), //36
FromLittleEndian<std::uint32_t, CharArray::value_type>(&MessageBlock[Index += sizeof(std::uint32_t)]), //40
FromLittleEndian<std::uint32_t, CharArray::value_type>(&MessageBlock[Index += sizeof(std::uint32_t)]), //44
FromLittleEndian<std::uint32_t, CharArray::value_type>(&MessageBlock[Index += sizeof(std::uint32_t)]), //48
FromLittleEndian<std::uint32_t, CharArray::value_type>(&MessageBlock[Index += sizeof(std::uint32_t)]), //52
FromLittleEndian<std::uint32_t, CharArray::value_type>(&MessageBlock[Index += sizeof(std::uint32_t)]), //56
FromLittleEndian<std::uint32_t, CharArray::value_type>(&MessageBlock[Index]) //60
};[/source]
Also, which would you consider more readable (assuming the result is correct in the first place). I'm conflicted since I consider the original version more readable, but something about having the index numbers hard coded bugs me. Or should I just replace this with a for loop and not try to initialize the array like this? I was trying to avoid the double initialization, since I believe that std::array will initialize all of the values to 0 (please correct me if I'm wrong here).