Converting from base 16 to base 10 in reverse byte order
Categories:
Converting Base-16 (Hex) to Base-10 (Decimal) with Reverse Byte Order

Learn how to accurately convert hexadecimal strings representing byte sequences in reverse (little-endian) order into their decimal equivalents in C# for network programming and data parsing.
When working with binary data, especially in network programming or low-level system interactions, you often encounter hexadecimal strings that represent numerical values. A common challenge arises when these hexadecimal strings represent multi-byte numbers stored in reverse byte order, also known as little-endian. This article will guide you through the process of converting such base-16 strings into their base-10 (decimal) equivalents using C#.
Understanding Byte Order (Endianness)
Endianness refers to the order in which bytes are stored in computer memory or transmitted over a network. There are two primary types:
- Big-Endian: The most significant byte (MSB) comes first. This is often considered the 'natural' order, similar to how we write numbers (e.g., in
0x12345678
,12
is the MSB). - Little-Endian: The least significant byte (LSB) comes first. This is common in Intel x86 architectures and many network protocols. In
0x12345678
, if stored little-endian, the bytes would appear as78 56 34 12
in memory.
When you receive a hexadecimal string like "0100"
that represents a 16-bit integer, and you know it's in reverse byte order, it means the actual value is 0001
(hex), which is 1
(decimal). If it were "0001"
, it would represent 0100
(hex), which is 256
(decimal). Correctly handling this reversal is crucial for accurate data interpretation.
flowchart LR A["Input Hex String (e.g., '0100')"] --> B{"Is it reverse byte order?"} B -->|Yes| C["Reverse Byte Pairs (e.g., '0001')"] B -->|No| D["Keep as is (e.g., '0100')"] C --> E["Convert Hex to Decimal"] D --> E E --> F["Output Decimal Value"] style A fill:#f9f,stroke:#333,stroke-width:2px style F fill:#bbf,stroke:#333,stroke-width:2px
Process flow for converting hexadecimal strings with potential byte order reversal.
Implementation in C#
C# provides robust methods for parsing hexadecimal strings. The key challenge here is to correctly reverse the byte order before parsing the full hexadecimal string into a numerical type. This involves treating the hex string as a sequence of byte pairs, reversing their order, and then concatenating them back into a new hex string for conversion.
using System;
using System.Linq;
using System.Globalization;
public static class HexConverter
{
/// <summary>
/// Converts a hexadecimal string representing a number in reverse byte order
/// (little-endian) to its base-10 (decimal) equivalent.
/// </summary>
/// <param name="hexString">The hexadecimal string (e.g., "0100" for 256, "AABBCCDD" for 3735928559).</param>
/// <returns>The decimal equivalent of the reversed hex string.</returns>
/// <exception cref="ArgumentException">Thrown if the hex string is null, empty, or has an odd length.</exception>
/// <exception cref="FormatException">Thrown if the hex string contains invalid hex characters.</exception>
public static long ConvertReverseByteHexToDecimal(string hexString)
{
if (string.IsNullOrEmpty(hexString))
{
throw new ArgumentException("Hex string cannot be null or empty.", nameof(hexString));
}
if (hexString.Length % 2 != 0)
{
throw new ArgumentException("Hex string must have an even length.", nameof(hexString));
}
// Step 1: Split the hex string into byte pairs and reverse their order.
// Example: "AABBCCDD" -> ["AA", "BB", "CC", "DD"] -> ["DD", "CC", "BB", "AA"]
string reversedHex = string.Concat(Enumerable.Range(0, hexString.Length / 2)
.Select(i => hexString.Substring(i * 2, 2))
.Reverse());
// Step 2: Convert the reversed hex string to a long (base-10).
// Use NumberStyles.HexNumber to specify base 16 parsing.
return long.Parse(reversedHex, NumberStyles.HexNumber);
}
public static void Main(string[] args)
{
// Example Usage:
string hex1 = "0100"; // Represents 0x0001 (1 decimal)
string hex2 = "AABBCCDD"; // Represents 0xDDCCBBAA (3735928559 decimal)
string hex3 = "FF"; // Represents 0xFF (255 decimal)
string hex4 = "00"; // Represents 0x00 (0 decimal)
Console.WriteLine($"'{hex1}' (reversed) -> {ConvertReverseByteHexToDecimal(hex1)}");
Console.WriteLine($"'{hex2}' (reversed) -> {ConvertReverseByteHexToDecimal(hex2)}");
Console.WriteLine($"'{hex3}' (reversed) -> {ConvertReverseByteHexToDecimal(hex3)}");
Console.WriteLine($"'{hex4}' (reversed) -> {ConvertReverseByteHexToDecimal(hex4)}");
// Expected Output:
// '0100' (reversed) -> 1
// 'AABBCCDD' (reversed) -> 3735928559
// 'FF' (reversed) -> 255
// '00' (reversed) -> 0
}
}
C# method to convert a reverse-byte-order hexadecimal string to a decimal long.
long.Parse()
method with NumberStyles.HexNumber
is powerful. It can parse hexadecimal strings of varying lengths, up to the maximum value of a long
(64-bit integer). For smaller values, you can use int.Parse()
or short.Parse()
accordingly, but ensure the resulting value fits the data type.Alternative: Using BitConverter
for Byte Arrays
If you are working directly with byte arrays (e.g., from a network stream) rather than hex strings, the BitConverter
class offers a more direct approach. You would first convert the hex string to a byte array, then potentially reverse the array if the system's endianness differs from the data's endianness, and finally use BitConverter
to get the numerical value.
using System;
using System.Linq;
using System.Globalization;
public static class HexConverterWithBytes
{
/// <summary>
/// Converts a hexadecimal string to a byte array.
/// </summary>
/// <param name="hex">The hexadecimal string.</param>
/// <returns>A byte array.</returns>
public static byte[] HexStringToByteArray(string hex)
{
if (hex.Length % 2 != 0)
{
throw new ArgumentException("Hex string must have an even length.", nameof(hex));
}
return Enumerable.Range(0, hex.Length)
.Where(x => x % 2 == 0)
.Select(x => byte.Parse(hex.Substring(x, 2), NumberStyles.HexNumber))
.ToArray();
}
public static void Main(string[] args)
{
string hexString = "AABBCCDD"; // Represents 0xDDCCBBAA in little-endian
// Step 1: Convert hex string to byte array
byte[] bytes = HexStringToByteArray(hexString);
// bytes will be { 0xAA, 0xBB, 0xCC, 0xDD }
Console.WriteLine($"Original bytes: {BitConverter.ToString(bytes)}");
// Step 2: Reverse the byte array if the source is little-endian and target is big-endian (or vice-versa)
// BitConverter.IsLittleEndian tells us the current system's endianness.
// If the source data is little-endian and our system is big-endian, or vice-versa, we need to reverse.
// For this problem, we assume the input hex string 'AABBCCDD' is already in the order it would appear in memory
// if it were little-endian, meaning 0xDD is the LSB and 0xAA is the MSB. So we reverse it to get the logical order.
Array.Reverse(bytes); // bytes becomes { 0xDD, 0xCC, 0xBB, 0xAA }
Console.WriteLine($"Reversed bytes: {BitConverter.ToString(bytes)}");
// Step 3: Convert byte array to long using BitConverter
// Note: BitConverter methods expect the bytes in the system's native endianness.
// Since we reversed the array to match the logical order (MSB first for parsing), it works.
long result = BitConverter.ToInt64(bytes, 0);
Console.WriteLine($"'{hexString}' (via BitConverter) -> {result}");
// Example with a 4-byte integer (int)
string hexStringInt = "01000000"; // Represents 0x00000001 in little-endian
byte[] bytesInt = HexStringToByteArray(hexStringInt);
Array.Reverse(bytesInt); // bytesInt becomes { 0x00, 0x00, 0x00, 0x01 }
int resultInt = BitConverter.ToInt32(bytesInt, 0);
Console.WriteLine($"'{hexStringInt}' (via BitConverter) -> {resultInt}");
// Expected Output:
// Original bytes: AA-BB-CC-DD
// Reversed bytes: DD-CC-BB-AA
// 'AABBCCDD' (via BitConverter) -> 3735928559
// '01000000' (via BitConverter) -> 1
}
}
Converting a hexadecimal string to a decimal long using byte array manipulation and BitConverter
.
BitConverter
. BitConverter.ToInt64
expects an 8-byte array, ToInt32
expects a 4-byte array, and so on. If your byte array is shorter, you'll need to pad it with zeros or use a different approach to avoid ArgumentException
.Choosing the Right Approach
Both methods presented achieve the same goal, but their suitability depends on your input format:
long.Parse(reversedHex, NumberStyles.HexNumber)
: This approach is generally simpler and more direct if your input is already a hexadecimal string and you need to handle the byte order reversal at the string level. It's less prone to errors related to byte array lengths.BitConverter
with byte array manipulation: This is more appropriate if you are already dealing with rawbyte[]
data, or if you need to perform other byte-level operations. It also gives you more explicit control over endianness handling, especially when interacting with hardware or network protocols where the system's native endianness might differ from the data's endianness.
1. Identify the input format
Determine if your input is a hexadecimal string or a raw byte array.
2. Confirm byte order
Verify if the hexadecimal string or byte array represents a number in little-endian (reverse byte) order.
3. Reverse byte pairs (if string input)
If using a hex string, split it into 2-character byte pairs and reverse their order to form a new hex string.
4. Convert to decimal
Use long.Parse()
with NumberStyles.HexNumber
for the reversed hex string, or convert the byte array to the appropriate numerical type using BitConverter
after ensuring correct byte order.
5. Validate results
Test with known values to ensure your conversion logic is correct.