<p>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.</p>

<p>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).</p>

<p>One excellent example, however, is the EncodeBase58() function in Bitcoin's <a href="https://github.com/bitcoin/bitcoin/blob/master/src/base58.h" rel="nofollow">base58.h</a> which uses a char vector and C++'s built-in reverse_copy function to reverse the elements' order in the vector:</p>

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

<p>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.</p>

CC BY-SA 3.0
2012-10-09T23:39:17.053Z
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.
ConstableJoe
CC BY-SA 3.0
2012-10-10T00:08:38.960Z
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.
David Perry
CC BY-SA 3.0
2012-10-10T00:10:25.917Z
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.
ConstableJoe
CC BY-SA 3.0
2012-10-10T00:16:33.770Z
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.
David Perry
CC BY-SA 3.0
2012-10-10T00:18:44.720Z
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.
David Perry
CC BY-SA 3.0
2012-10-10T00:45:36.853Z
No problem, welcome to StackExchange!
David Perry
CC BY-SA 3.0
2012-10-09T21:33:02.447Z
2012-10-10T00:33:20.583Z
2012-10-10T00:33:20.583Z
David Perry
<p>This answer seems simple, but I'm finding mixed answers. <a href="https://stackoverflow.com/questions/9245235/golang-midstate-sha-256-hash/9322486#9322486">This question</a> 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 <a href="https://bitcoin.stackexchange.com/questions/2925/pool-getwork-target">here</a> it's described as just a string reversal. Both seem correct in their contexts, so what's really going on?</p>

<endianness>
How is the endian conversion done?
ConstableJoe
# How is the endian conversion done?

(Asked by: username_0 on 2012-10-09)

This answer seems simple, but I'm finding mixed answers. [This question](https://stackoverflow.com/questions/9245235/golang-midstate-sha-256-hash/9322486#9322486) 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](https://bitcoin.stackexchange.com/questions/2925/pool-getwork-target) it's described as just a string reversal. Both seem correct in their contexts, so what's really going on?

**Tags:** endianness


---

## 1 answers

### Answer by username_1 on 2012-10-09. Score: 3 | Accepted answer

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 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.

> **Comments:**
> **username_0**: 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.  
> **username_1**: 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.  
> **username_0**: 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.  
> **username_1**: 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.  
> **username_1**: 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.  
> **username_1**: No problem, welcome to StackExchange!  

---

