4

This answer seems simple, but I'm finding mixed answers. This question describes the conversion from little-endian to big-endian hex strings (or vice-versa) as switching the order of bytes in every slice of four bytes, where here it's described as just a string reversal. Both seem correct in their contexts, so what's really going on?

3

In general, converting between big and little endian values depends on exactly how you're storing those values, so both of your examples could be correct in different implementations. To this end, techniques are likely to vary even within the same application since it's more dependent on how your input data is formatted.

It's also dependent on how your particular use case defines endianness - there's no one-size-fits-all definition - endianness can refer to the order of 8-bit bytes within a 16, 32 or 64 bit word or it could refer to the order of individual bits or even the order of entire words within a larger context. If you're encoding the 16-bit word "07F3" for example and your definition of endian refers to bytes within a word then big-endian would be "07F3" and little-endian would be "F307" - working with a 4-bit byte you would end up with "07F3" and "3F70" and working with individual bits big-endian would be "0111 1111 0011" (07F3) and little-endian would be "1100 1111 1110" (0CFE).

One excellent example, however, is the EncodeBase58() function in Bitcoin's base58.h which uses a char vector and C++'s built-in reverse_copy function to reverse the elements' order in the vector:

// Convert big endian data to little endian
// Extra zero at the end make sure bignum will interpret as a positive number
std::vector<unsigned char> vchTmp(pend-pbegin+1, 0);
reverse_copy(pbegin, pend, vchTmp.begin());

Now I'm not 100% sure but I believe that what's being passed in to the encode functions is a UTF-8 encoded string representation of the value, so in your own words it would seem that Bitcoin's endianness conversion - at least where Base58 conversion is concerned - is a simple string reversal as long as the input is UTF-8 encoded.

6
  • So essentially endianness is a string reversal (when we're talking about string representations of hex numbers), but for some values (like the getwork target) there's only a single number, and for others (like the block header data) there is a sequence so to change endianness one must reverse the string representing each individual number while the sequence of numbers overall is preserved. Oct 9 '12 at 23:39
  • Well there's always just the one number, it just depends how you're expressing it and how you're breaking it into the chunks (bits, bytes, words of varying size) that define endianness. Oct 10 '12 at 0:08
  • Ah, I believe my previous comment was incorrect. As you point out, since we have 8-bit bytes the pattern is reversing a string in character pairs. Oct 10 '12 at 0:10
  • Character pairs if your input string is in hex, yes. If you're using UTF-8, Base 64 or some other encoding method your methods will vary. It makes more sense if you always imagine your data in binary and then reverse the order of n-bit chunks, that way using different bases is less likely to throw you. Oct 10 '12 at 0:16
  • For example, in base 64 each character is 6 bits, so you'd be breaking your data into one-and-a-third character chunks and reversing their order - it just wouldn't work without switching bases or working exclusively at the bit-level. Oct 10 '12 at 0:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.