Converting from hex to string - c#

I need to check for a string located inside a packet that I receive as byte array. If I use BitConverter.ToString(), I get the bytes as string with dashes (f.e.: 00-50-25-40-A5-FF).
I tried most functions I found after a quick googling, but most of them have input parameter type string and if I call them with the string with dashes, It throws an exception.
I need a function that turns hex(as string or as byte) into the string that represents the hexadecimal value(f.e.: 0x31 = 1). If the input parameter is string, the function should recognize dashes(example "47-61-74-65-77-61-79-53-65-72-76-65-72"), because BitConverter doesn't convert correctly.

Like so?
static void Main()
{
byte[] data = FromHex("47-61-74-65-77-61-79-53-65-72-76-65-72");
string s = Encoding.ASCII.GetString(data); // GatewayServer
}
public static byte[] FromHex(string hex)
{
hex = hex.Replace("-", "");
byte[] raw = new byte[hex.Length / 2];
for (int i = 0; i < raw.Length; i++)
{
raw[i] = Convert.ToByte(hex.Substring(i * 2, 2), 16);
}
return raw;
}

For Unicode support:
public class HexadecimalEncoding
{
public static string ToHexString(string str)
{
var sb = new StringBuilder();
var bytes = Encoding.Unicode.GetBytes(str);
foreach (var t in bytes)
{
sb.Append(t.ToString("X2"));
}
return sb.ToString(); // returns: "48656C6C6F20776F726C64" for "Hello world"
}
public static string FromHexString(string hexString)
{
var bytes = new byte[hexString.Length / 2];
for (var i = 0; i < bytes.Length; i++)
{
bytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16);
}
return Encoding.Unicode.GetString(bytes); // returns: "Hello world" for "48656C6C6F20776F726C64"
}
}

string str = "47-61-74-65-77-61-79-53-65-72-76-65-72";
string[] parts = str.Split('-');
foreach (string val in parts)
{
int x;
if (int.TryParse(val, out x))
{
Console.Write(string.Format("{0:x2} ", x);
}
}
Console.WriteLine();
You can split the string at the -
Convert the text to ints (int.TryParse)
Output the int as a hex string {0:x2}

string hexString = "8E2";
int num = Int32.Parse(hexString, System.Globalization.NumberStyles.HexNumber);
Console.WriteLine(num);
//Output: 2274
From https://msdn.microsoft.com/en-us/library/bb311038.aspx

Your reference to "0x31 = 1" makes me think you're actually trying to convert ASCII values to strings - in which case you should be using something like Encoding.ASCII.GetString(Byte[])

If you need the result as byte array, you should pass it directly without changing it to a string, then change it back to bytes.
In your example the (f.e.: 0x31 = 1) is the ASCII codes. In that case to convert a string (of hex values) to ASCII values use:
Encoding.ASCII.GetString(byte[])
byte[] data = new byte[] { 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30 };
string ascii=Encoding.ASCII.GetString(data);
Console.WriteLine(ascii);
The console will display: 1234567890

My Net 5 solution that also handles null characters at the end:
hex = ConvertFromHex( hex.AsSpan(), Encoding.Default );
static string ConvertFromHex( ReadOnlySpan<char> hexString, Encoding encoding )
{
int realLength = 0;
for ( int i = hexString.Length - 2; i >= 0; i -= 2 )
{
byte b = byte.Parse( hexString.Slice( i, 2 ), NumberStyles.HexNumber, CultureInfo.InvariantCulture );
if ( b != 0 ) //not NULL character
{
realLength = i + 2;
break;
}
}
var bytes = new byte[realLength / 2];
for ( var i = 0; i < bytes.Length; i++ )
{
bytes[i] = byte.Parse( hexString.Slice( i * 2, 2 ), NumberStyles.HexNumber, CultureInfo.InvariantCulture );
}
return encoding.GetString( bytes );
}

One-liners:
var input = "Hallo Hélène and Mr. Hörst";
var ConvertStringToHexString = (string input) => String.Join("", Encoding.UTF8.GetBytes(input).Select(b => $"{b:X2}"));
var ConvertHexToString = (string hexInput) => Encoding.UTF8.GetString(Enumerable.Range(0, hexInput.Length / 2).Select(_ => Convert.ToByte(hexInput.Substring(_ * 2, 2), 16)).ToArray());
Assert.AreEqual(input, ConvertHexToString(ConvertStringToHexString(input)));

Related

C# How convert unHex to String

I'm trying to convert an unHex value to a string but it's not working.
I have the following value 0x01BB92E7F716F55B144768FCB2EA40187AE6CF6B2E52A64F7331D0539507441F7D770112510D679F0B310116B0D709E049A19467672FFA532A7C30DFB72
Result I hope would be this
but executing the function below displays this result
»’ Ç ÷ õ [Ghü²ê # zæÏk.R¦Os1ÐS • D} w Q gŸ 1 ° × àI¡ ”gg / úS * | 0ß ·) = ¤
Any idea how I can extract the information as expected
public static string Hex2String (string input)
{
var builder = new StringBuilder ();
for (int i = 0; i < socketLength; i + = 2)
{
// throws an exception if not properly formatted
string hexdec = input.Substring (i, 2);
int number = Int32.Parse (hexdec, NumberStyles.HexNumber);
char charToAdd = (char) number;
builder.Append (charToAdd);
}
return builder.ToString ();
}
Your result is base64-encoded. Base64 is a way of taking a byte array and turning it into human-readable characters.
Your code tries to take these raw bytes and cast them to chars, but not all byte values are valid printable characters: some are control characters, some can't be printed, etc.
Instead, let's turn the hex string into a byte array, and then turn that byte array into a base64 string.
string input = "01BB92E7F716F55B144768FCB2EA40187AE6CF6B2E52A64F7331D0539507441F7D770112510D679F0B310116B0D709E049A19467672FFA532A7C30DFB72";
byte[] bytes = new byte[input.Length / 2];
for (int i = 0; i < bytes.Length; i++)
{
bytes[i] = byte.Parse(input.Substring(i * 2, 2), NumberStyles.HexNumber);
}
string result = Convert.ToBase64String(bytes);
This results in:
AbuS5/cW9VsUR2j8supAGHrmz2suUqZPczHQU5UHRB99dwESUQ1nnwsxARaw1wngSaGUZ2cv+lMqfDDftw==
See it running here.

Conversion of Hexadecimal to text [duplicate]

I need to check for a string located inside a packet that I receive as byte array. If I use BitConverter.ToString(), I get the bytes as string with dashes (f.e.: 00-50-25-40-A5-FF).
I tried most functions I found after a quick googling, but most of them have input parameter type string and if I call them with the string with dashes, It throws an exception.
I need a function that turns hex(as string or as byte) into the string that represents the hexadecimal value(f.e.: 0x31 = 1). If the input parameter is string, the function should recognize dashes(example "47-61-74-65-77-61-79-53-65-72-76-65-72"), because BitConverter doesn't convert correctly.
Like so?
static void Main()
{
byte[] data = FromHex("47-61-74-65-77-61-79-53-65-72-76-65-72");
string s = Encoding.ASCII.GetString(data); // GatewayServer
}
public static byte[] FromHex(string hex)
{
hex = hex.Replace("-", "");
byte[] raw = new byte[hex.Length / 2];
for (int i = 0; i < raw.Length; i++)
{
raw[i] = Convert.ToByte(hex.Substring(i * 2, 2), 16);
}
return raw;
}
For Unicode support:
public class HexadecimalEncoding
{
public static string ToHexString(string str)
{
var sb = new StringBuilder();
var bytes = Encoding.Unicode.GetBytes(str);
foreach (var t in bytes)
{
sb.Append(t.ToString("X2"));
}
return sb.ToString(); // returns: "48656C6C6F20776F726C64" for "Hello world"
}
public static string FromHexString(string hexString)
{
var bytes = new byte[hexString.Length / 2];
for (var i = 0; i < bytes.Length; i++)
{
bytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16);
}
return Encoding.Unicode.GetString(bytes); // returns: "Hello world" for "48656C6C6F20776F726C64"
}
}
string str = "47-61-74-65-77-61-79-53-65-72-76-65-72";
string[] parts = str.Split('-');
foreach (string val in parts)
{
int x;
if (int.TryParse(val, out x))
{
Console.Write(string.Format("{0:x2} ", x);
}
}
Console.WriteLine();
You can split the string at the -
Convert the text to ints (int.TryParse)
Output the int as a hex string {0:x2}
string hexString = "8E2";
int num = Int32.Parse(hexString, System.Globalization.NumberStyles.HexNumber);
Console.WriteLine(num);
//Output: 2274
From https://msdn.microsoft.com/en-us/library/bb311038.aspx
Your reference to "0x31 = 1" makes me think you're actually trying to convert ASCII values to strings - in which case you should be using something like Encoding.ASCII.GetString(Byte[])
If you need the result as byte array, you should pass it directly without changing it to a string, then change it back to bytes.
In your example the (f.e.: 0x31 = 1) is the ASCII codes. In that case to convert a string (of hex values) to ASCII values use:
Encoding.ASCII.GetString(byte[])
byte[] data = new byte[] { 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30 };
string ascii=Encoding.ASCII.GetString(data);
Console.WriteLine(ascii);
The console will display: 1234567890
My Net 5 solution that also handles null characters at the end:
hex = ConvertFromHex( hex.AsSpan(), Encoding.Default );
static string ConvertFromHex( ReadOnlySpan<char> hexString, Encoding encoding )
{
int realLength = 0;
for ( int i = hexString.Length - 2; i >= 0; i -= 2 )
{
byte b = byte.Parse( hexString.Slice( i, 2 ), NumberStyles.HexNumber, CultureInfo.InvariantCulture );
if ( b != 0 ) //not NULL character
{
realLength = i + 2;
break;
}
}
var bytes = new byte[realLength / 2];
for ( var i = 0; i < bytes.Length; i++ )
{
bytes[i] = byte.Parse( hexString.Slice( i * 2, 2 ), NumberStyles.HexNumber, CultureInfo.InvariantCulture );
}
return encoding.GetString( bytes );
}
One-liners:
var input = "Hallo Hélène and Mr. Hörst";
var ConvertStringToHexString = (string input) => String.Join("", Encoding.UTF8.GetBytes(input).Select(b => $"{b:X2}"));
var ConvertHexToString = (string hexInput) => Encoding.UTF8.GetString(Enumerable.Range(0, hexInput.Length / 2).Select(_ => Convert.ToByte(hexInput.Substring(_ * 2, 2), 16)).ToArray());
Assert.AreEqual(input, ConvertHexToString(ConvertStringToHexString(input)));

How to convert from decimal to binary invert it with ~ and convert back to decimal

Not sure if I am in the right direction.
I can't find info about tilde.
int n = 5;
int m = ~n;
string numAsString = Convert.ToString(~n, 2);
char[] NumAsChar = numAsString.ToCharArray();
long l = Convert.ToInt64(numAsString, 2);
Console.WriteLine(numAsString);
Console.WriteLine(l);
You're probably looking for a simple answer.
int n = 5;
byte[] nbytes = BitConverter.GetBytes(n);
for(int i = 0 ; i < nbytes.Length; i++)
nbytes[i] = ~nbytes[i];
n = BitConverter.ToInt32(nbytes, 0);
edit: you actually can't do ~ on a byte[]. You can either do
for(int i = 0 ; i < nbytes.Length; i++)
nbytes[i] = ~nbytes[i];
or just not use a byte array at all.
For clarity's sake, do note that you can just do
n = ~n;
and skip doing any of the separation. But you specifically asked for the byte conversion.
Use these 2 methods
static byte[] GetBytes(string str)
{
byte[] bytes = new byte[str.Length * sizeof(char)];
System.Buffer.BlockCopy(str.ToCharArray(), 0, bytes, 0, bytes.Length);
return bytes;
}
static string GetString(byte[] bytes)
{
char[] chars = new char[bytes.Length / sizeof(char)];
System.Buffer.BlockCopy(bytes, 0, chars, 0, bytes.Length);
return new string(chars);
}
And then use them like this
byte[] bytes = GetTheBytes(str);
byte[] reversed = bytes.Reverse().ToArray();
var revStr = GetString(reversed)
I did it like this.Any suggestions on making it simpler.
int n = 100;
//Convert decimal to binary
string numAsString = Convert.ToString(n, 2);
char[] NumAsChar = numAsString.ToCharArray();
Console.WriteLine(numAsString);
//Invert bits
for (int i = 0; i < numAsString.Length; i++)
{
if (NumAsChar[i] == '0')
{
NumAsChar[i] = '1';
}
else
{
NumAsChar[i] = '0';
}
}
string NewNumAsString = new string(NumAsChar);
//Convert inverted binary num to decimal
long l = Convert.ToInt64(NewNumAsString, 2);
Console.WriteLine(NewNumAsString);
Console.WriteLine(l);

Convert a bit-string to a char

I'm trying to convert a bit-string to ASCII characters by 8 bits (each 8 bits = 1 ASCII char).
public string BitsToChar(string InpS)
{
string RetS = "";
for (int iCounter = 0; iCounter < InpS.Length / 8; iCounter++)
RetS = System.String.Concat(RetS, (char)Convert.ToByte(InpS.Substring(iCounter * 8, 8)), 2);
return RetS;
}
It throws a System.OverflowException: Value was either too large or too small for an unsigned byte.
It's not clear for me how comes that an 8-bit portion of a binary string can be too small or too large for an 8-bit Byte type.
Any ideas? Thank you.
Try something like that:
private static Char ConvertToChar(String value) {
int result = 0;
foreach (Char ch in value)
result = result * 2 + ch - '0';
return (Char) result;
}
public string BitsToChar(string value) {
if (String.IsNullOrEmpty(value))
return value;
StringBuilder Sb = new StringBuilder();
for (int i = 0; i < value.Length / 8; ++i)
Sb.Append(ConvertToChar(value.Substring(8 * i, 8)));
return Sb.ToString();
}
...
String result = BitsToChar("010000010010000001100010"); // <- "A b"
Do something like this
public string BitsToChar(string InpS)
{
string RetS = "";
foreach (char c in InpS)
{
RetS = RetS + System.Convert.ToInt32(c);
}
return RetS;
}
Try something like that:
public static string BitsToChar(string bitString)
{
var retString = new StringBuilder();
foreach (Match match in Regex.Matches(bitString, "[01]{8}")) // 8 is size of bits
{
retString.Append((Char)Convert.ToByte(match.Value, 2));
}
return retString.ToString();
}

C# convert hexadecimal value in to UTF8 and ASCII

I am trying to convert a hexadecimal values in a string in to both ASCII value and UTF8 value. But when I execute the following code, it prints out the same hex value I give as input
string hexString = "68656c6c6f2c206d79206e616d6520697320796f752e";
System.Text.UTF8Encoding encoding=new System.Text.UTF8Encoding();
byte[] dBytes = encoding.GetBytes(hexString);
//To get ASCII value of the hex string.
string ASCIIresult = System.Text.Encoding.ASCII.GetString(dBytes);
MessageBox.Show(ASCIIresult, "Showing value in ASCII");
//To get the UTF8 value of the hex string
string utf8result = System.Text.Encoding.UTF8.GetString(dBytes);
MessageBox.Show(utf8result, "Showing value in UTF8");
Since you are naming a variable hexString, I assume that the value is already encoded into a hex format.
This means the following will not work:
string hexString = "68656c6c6f2c206d79206e616d6520697320796f752e";
System.Text.UTF8Encoding encoding=new System.Text.UTF8Encoding();
byte[] dBytes = encoding.GetBytes(hexString);
This is because you are treating the already encoded string as plain UTF8 text.
You are probably missing a step to convert the hex encoded string into a byte array.
You can do this using this SO post which shows this function:
public static byte[] StringToByteArray(String hex)
{
int NumberChars = hex.Length/2;
byte[] bytes = new byte[NumberChars];
using (var sr = new StringReader(hex))
{
for (int i = 0; i < NumberChars; i++)
bytes[i] =
Convert.ToByte(new string(new char[2]{(char)sr.Read(), (char)sr.Read()}), 16);
}
return bytes;
}
So, the end result would be this:
byte[] dBytes = StringToByteArray(hexString);
//To get ASCII value of the hex string.
string ASCIIresult = System.Text.Encoding.ASCII.GetString(dBytes);
MessageBox.Show(ASCIIresult, "Showing value in ASCII");
//To get the UTF8 value of the hex string
string utf8result = System.Text.Encoding.UTF8.GetString(dBytes);
MessageBox.Show(utf8result, "Showing value in UTF8");
You should first convert the hex string to a byte array:
byte[] dBytes = Enumerable.Range(0, hexString.Length)
.Where(x => x % 2 == 0)
.Select(x => Convert.ToByte(hexString.Substring(x, 2), 16))
.ToArray();
I've used this method to convert any
public static string FromHex (string h) //Put your sequence of hex to convert to string.
{
if (h.Length % 2 != 0)
throw new ArgumentException("The string " + nameof(h) + " is not a valid Hex.", nameof(h));
char[] CharFromHex = new char[h.Length / 2];
int j = 0;
for (int i = 0; i < h.Length; i += 2)
{
string hexSubStr = h.Substring(i, 2);
CharFromHex[j] = (char)Convert.ToInt32(hexSubStr, 16);
j += 1;
}
StringBuilder str = new StringBuilder();
str.Append(CharFromHex);
return str.ToString();
}

Categories

Resources