Converting a Hex String to a Byte Array

How do you convert a byte array to a hexadecimal string, and vice versa?

You can use Convert.ToHexString starting with .NET 5.

There's also a method for the reverse operation: Convert.FromHexString.


For older versions of .NET you can either use:

public static string ByteArrayToString(byte[] ba)
{
StringBuilder hex = new StringBuilder(ba.Length * 2);
foreach (byte b in ba)
hex.AppendFormat("{0:x2}", b);
return hex.ToString();
}

or:

public static string ByteArrayToString(byte[] ba)
{
return BitConverter.ToString(ba).Replace("-","");
}

There are even more variants of doing it, for example here.

The reverse conversion would go like this:

public static byte[] StringToByteArray(String hex)
{
int NumberChars = hex.Length;
byte[] bytes = new byte[NumberChars / 2];
for (int i = 0; i < NumberChars; i += 2)
bytes[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16);
return bytes;
}

Using Substring is the best option in combination with Convert.ToByte. See this answer for more information. If you need better performance, you must avoid Convert.ToByte before you can drop SubString.

hexadecimal string to byte array in python

Suppose your hex string is something like

>>> hex_string = "deadbeef"

Convert it to a bytearray (Python 3 and 2.7):

>>> bytearray.fromhex(hex_string)
bytearray(b'\xde\xad\xbe\xef')

Convert it to a bytes object (Python 3):

>>> bytes.fromhex(hex_string)
b'\xde\xad\xbe\xef'

Note that bytes is an immutable version of bytearray.

Convert it to a string (Python ≤ 2.7):

>>> hex_data = hex_string.decode("hex")
>>> hex_data
"\xde\xad\xbe\xef"

How can I convert a hex string to a byte array?

Here's a nice fun LINQ example.

public static byte[] StringToByteArray(string hex) {
return Enumerable.Range(0, hex.Length)
.Where(x => x % 2 == 0)
.Select(x => Convert.ToByte(hex.Substring(x, 2), 16))
.ToArray();
}

Convert a string representation of a hex dump to a byte array using Java?

Update (2021) - Java 17 now includes java.util.HexFormat (only took 25 years):

HexFormat.of().parseHex(s)


For older versions of Java:

Here's a solution that I think is better than any posted so far:

/* s must be an even-length string. */
public static byte[] hexStringToByteArray(String s) {
int len = s.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
+ Character.digit(s.charAt(i+1), 16));
}
return data;
}

Reasons why it is an improvement:

  • Safe with leading zeros (unlike BigInteger) and with negative byte values (unlike Byte.parseByte)

  • Doesn't convert the String into a char[], or create StringBuilder and String objects for every single byte.

  • No library dependencies that may not be available

Feel free to add argument checking via assert or exceptions if the argument is not known to be safe.

Converting a hex string to a byte array

This ought to work:

int char2int(char input)
{
if(input >= '0' && input <= '9')
return input - '0';
if(input >= 'A' && input <= 'F')
return input - 'A' + 10;
if(input >= 'a' && input <= 'f')
return input - 'a' + 10;
throw std::invalid_argument("Invalid input string");
}

// This function assumes src to be a zero terminated sanitized string with
// an even number of [0-9a-f] characters, and target to be sufficiently large
void hex2bin(const char* src, char* target)
{
while(*src && src[1])
{
*(target++) = char2int(*src)*16 + char2int(src[1]);
src += 2;
}
}

Depending on your specific platform there's probably also a standard implementation though.

C# - Convert hex string to byte array of hex values

string hexIpAddress = "0A010248"; // 10.1.2.72 => "0A010248"
byte[] bytes = new byte[hexIpAddress.Length / 2];

for (int i = 0; i < hexIpAddress.Length; i += 2)
bytes[i/2] = Convert.ToByte(hexIpAddress.Substring(i, 2), 16);

This results in this array:

bytes = {0x0A, 0x01, 0x02, 0x48}; 

or represented as decimals:

bytes = {10, 1, 2, 72};

or as binaries 00001010, 000000001, 00000010, 01001000 (binary literals are still not supported in C#6).

The values are the same, there is no representation in any base in byte. You can only decide how the values should be represented when converting them to strings again:

foreach(byte b in bytes)
Console.WriteLine("{0} {0:X}", b);

results in

10 A
1 1
2 2
72 48

C# Convert Hex String Array to Byte Array

You have to convert (or parse) string in order to get byte since string and byte are different types:

// 10 == 10d 
byte b = Convert.ToByte("10"); // if "10" is a decimal representation
// 16 == 0x10
byte b = Convert.ToByte("10", 16); // if "10" is a hexadecimal representation

If you want to process an array, you can try a simple Linq:

using System.Linq;

...

string[] hexValues = new string[] {
"10", "0F", "3E", "42"};

byte[] result = hexValues
.Select(value => Convert.ToByte(value, 16))
.ToArray();

If you want to print out result as hexadecimal, use formatting ("X2" format string - at least 2 hexadecimal digits, use captital letters):

// 10, 0F, 3E, 42
Console.Write(string.Join(", ", result.Select(b => b.ToString("X2"))));

Compare with same array but in a different format ("d2" - at least 2 decimal digits)

// 16, 15, 62, 66 
Console.Write(string.Join(", ", result.Select(b => b.ToString("d2"))));

If no format provided, .Net uses default one and represents byte in decimal:

// 16, 15, 62, 66 
Console.Write(string.Join(", ", result));

Is there a way to convert Hex string to bytes using Java streams?

The simplest way to convert a hex string to a byte array, is JDK 17’s HexFormat.parseHex(…).

byte[] bytes = HexFormat.of().parseHex("c0ffeec0de");
System.out.println(Arrays.toString(bytes));
System.out.println(HexFormat.of().formatHex(bytes));
[-64, -1, -18, -64, -34]
c0ffeec0de

This is the most convenient method, as can also handle formatted input, e.g.

byte[] bytes = HexFormat.ofDelimiter(" ").withPrefix("0x")
.parseHex("0xc0 0xff 0xee 0xc0 0xde");

Note that if you have to process an entire file, even a straight-forward

String s = Files.readString(pathToYourFile);
byte[] bytes = HexFormat.of().parseHex(s);

may run with reasonable performance, as long as you have enough temporary memory. If the preconditions are met, which is the case for ASCII based charsets and hex strings, the readString method will read into an array which will become the resulting string’s backing buffer. In other words, the implicit copying between buffers, intrinsic to other approaches, is skipped.

There’s some time spent in checking the preconditions though, which we could skip:

String s = Files.readString(pathToYourFile, StandardCharsets.ISO_8859_1);
byte[] bytes = HexFormat.of().parseHex(s);

This enforces the same encoding used by the compact strings since JDK 9. Since hex strings consist of ASCII characters only, it will correctly interpret all sources whose charset is ASCII based¹. Only for incorrect sources, a misinterpretation of the wrong characters may occur in the exception message.

It’s hard to beat that and if using JDK 17 is an option, trying an alternative is not worth the effort. But if you are using an older JDK, you may parse a file like

byte[] bytes;
try(FileChannel fch = FileChannel.open(pathToYourFile, StandardOpenOption.READ)) {
bytes = hexStringToBytes(fch.map(MapMode.READ_ONLY, 0, fch.size()));
}
public static byte[] hexStringToBytes(ByteBuffer hexBytes) {
byte[] bytes = new byte[hexBytes.remaining() >> 1];
for(int i = 0; i < bytes.length; i++)
bytes[i] = (byte)((Character.digit(hexBytes.get(), 16) << 4)
| Character.digit(hexBytes.get(), 16));
return bytes;
}

This does also utilize the fact that hex strings are ASCII based, so unless you use a rather uncommon charset/encoding, we can process the file data short-cutting the charset conversions. This approach will also work if there’s not enough physical memory to keep the entire file, but then, the performance will be lower, of course.

The file also must not be larger than 2GiB to use a single memory mapping operation. Performing the operation in multiple memory mapping steps is possible, but you’ll soon run into the array length limit for the result, so if that’s an issue, you have to rethink the entire approach anyway.

¹ so this won’t work for UTF-16 nor EBCDIC, the only two counter examples you might have to deal with in real life, though even these are very rare.

How to correctly convert a Hex String to Byte Array in C?

You can use strtol() instead.

Simply replace this line:

sscanf(pos, "%2hhx", &val[count]);

with:

char buf[10];
sprintf(buf, "0x%c%c", pos[0], pos[1]);
val[count] = strtol(buf, NULL, 0);

UPDATE: You can avoid using sprintf() using this snippet instead:

char buf[5] = {"0", "x", pos[0], pos[1], 0};
val[count] = strtol(buf, NULL, 0);


Related Topics



Leave a reply



Submit