Wednesday, March 5, 2008

Convert Hex String to Byte Array and Vice-Versa

If you've dealt with legacy encryption schemes across multiple platforms, you know what a chore it can be to deal with the various encoding options, the character sets, etc. Sure, Microsoft provides various short-cuts for converting hex strings to/from byte arrays (BitConverter, Encoding.ASCII.GetBytes, etc) that seem to sometimes work depending on the details of what you're doing and the systems involved.. but time and again I wind up going back to an old tried-and-true method shown below.


/// <summary>
/// Convert string to byte_array
/// </summary>
/// <param name="strInput">
private byte[] String_To_Bytes(string strInput)
{
// i variable used to hold position in string
int i = 0;
// x variable used to hold byte array element position
int x = 0;
// allocate byte array based on half of string length
byte[] bytes = new byte[(strInput.Length) / 2];
// loop through the string - 2 bytes at a time converting
// it to decimal equivalent and store in byte array
while (strInput.Length > i + 1)
{
long lngDecimal = Convert.ToInt32(strInput.Substring(i, 2), 16);
bytes[x] = Convert.ToByte(lngDecimal);
i = i + 2;
++x;
}
// return the finished byte array of decimal values
return bytes;
}

/// <summary>
/// Convert byte_array to string
/// </summary>
/// <param name="bytes_Input">
private string Bytes_To_String(byte[] bytes_Input)
{
// convert the byte array back to a true string
string strTemp = "";
for (int x = 0; x <= bytes_Input.GetUpperBound(0); x++)
{
int number = int.Parse(bytes_Input[x].ToString());
strTemp += number.ToString("X").PadLeft(2, '0');
}
// return the finished string of hex values
return strTemp;
}

This allows you, for example, to go from a string value of say "A5B2FFD0" back and forth between the equivalent byte array { 0xA5, 0xB2, 0xFF, 0xD0 }.

5 comments:

James Curran said...

Your String_to_bytes is more or less reasonable, although it can be toned up a bit:

private byte[] String_To_Bytes2(string strInput)
{
// allocate byte array based on half of string length
int numBytes = (strInput.Length) / 2;
byte[] bytes = new byte[numBytes];

// loop through the string - 2 bytes at a time converting it to decimal equivalent and store in byte array
// x variable used to hold byte array element position
for(int x=0; x<numBytes; ++x)
{
bytes[x] = Convert.ToByte(strInput.Substring(x*2, 2), 16);
}

// return the finished byte array of decimal values
return bytes;
}

Bytes_To_String on the other hand, is more of a mess:

// convert the byte array back to a true string
private string Bytes_To_String2(byte[] bytes_Input)
{
StringBuilder strTemp = new StringBuilder(bytes_Input.Length *2);
foreach(byte b in bytes_Input)
{
strTemp.Append(b.ToString("X02"));
}
return strTemp.ToString();
}

Kenneth Scott said...

james-
nice job on the cleanup. that code is several years old and definitely needed to be cleaned up. thanks-

Anonymous said...

great, thanks

Anonymous said...

anyone know how to do it in VB.Net?

Kenneth Scott said...

It should really be pretty trivial to port to vb.net. Although I sometimes have mixed results, you can probably even use one of the online code converters like this one to get you started:
http://www.developerfusion.com/tools/convert/csharp-to-vb/

good luck-

Post a Comment