c# bitconverter.ToString convert to hexadecimal string - c#

I am using BitConverter.ToString(bytes) for converting by string to hexadecimal string which I further convert it into integer or float.
But the input stream consist of 0 to show that byte value is 0. So suppose I have an integer which is represented by 2 bytes of input starting at position x and the first consist of EE while 2nd byte is 00. Now when I use BitConverter.ToString(bytes, x, 2).Replace ("-","") I get output as EE00 whose integer value is 60928 but in this case the output should be 238 that is converting only first byte EE to integer.
But in some other case the 2 bytes might be EE01 whose integer value will 60929 which is correct in this case.
Any suggestion how can I solve my problem?
Since some people are saying that question is confusing I will restate my problem I have long hexadecimal string as input. In hexadecimal string the
1) First 12 bytes represent string.
2) next 11 bytes also represent some other string.
3) Next 1 byte represent integer.
4) Next 3 bytes represent integer.
5) Next 4 bytes represent integer.
6) Next 4 bytes represent float.
7) Next 7 bytes represent string.
8) Next 5 bytes represent integer.
So for 4th case if bytes are ee 00 00 then I should neglect 0's and convert ee to integer. But if it ee 00 ee then I should convert ee00ee to integer. Also every time I will be following same pattern as mentioned above.

This method converts a hex string to a byte array.
public static byte[] ConvertHexString(string hex)
{
Contract.Requried(!string.IsNullOrEmpty(hex));
// get length
var len = hex.Length;
if (len % 2 == 1)
{
throw new ArgumentException("hexValue: " + hex);
}
var lenHalf = len / 2;
// create a byte array
var bs = new byte[lenHalf];
try
{
// convert the hex string to bytes
for (var i = 0; i != lenHalf; i++)
{
bs[i] = (byte)int.Parse(hex.Substring(i * 2, 2), NumberStyles.HexNumber, CultureInfo.InvariantCulture);
}
}
catch (Exception ex)
{
throw new ParseException(ex.Message, ex);
}
// return the byte array
return bs;
}
From the other side:
public static string ConvertByteToHexString(byte num)
{
var text = BitConverter.ToString(new[] { num });
if (text.Length == 1)
{
text = "0" + text;
}
return text;
}

My problem has been solved. I was making a mistake of Endianness. I was receiving the data as EE 00 and I should have taken it as 00 EE before converting to integer. Thanks to all who gave me solution for my problem and sorry for missing out this important fact from question.

Related

Is it possible to convert a string to byte array in binary representation

I need to convert an integer which in the form of string to byte array in binary representation.
For example : I have a value "29", then convert this value to binary equivalent 2-> 0010 and 9-> 1001 and store it in byte array where 0th index has 0010 and 1st index has 1001.
I have tried this but this gives me an array of 8 bytes.
var val = "29".ToCharArray();
var a = Convert.ToString(Convert.ToInt32(Convert.ToString(val[0])), 2).PadLeft(4, '0');
var b = Convert.ToString(Convert.ToInt32(Convert.ToString(val[1])), 2).PadLeft(4, '0');
var c = a.ToList();
c.ForEach(x => sb.Append(Convert.ToString(x) + " "));
var f = sb.ToString().Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
var g = f.ToList();
byte[] buff = new byte[g.Count];
for (int z = 0; z < g.Count; z++)
{
buff[z] = (byte)Convert.ToInt32(g[z]);
}
var h = b.ToList();
sb.Clear();
h.ForEach(x => sb.Append(Convert.ToString(x) + " "));
var i = sb.ToString().Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
var j = i.ToList();
byte[] buff2 = new byte[j.Count];
for (int k = 0; k < j.Count; k++)
{
buff2[k] = (byte)Convert.ToInt32(j[k]);
}
byte[] buffer = buff.Concat(buff2).ToArray();
You can do this much easier:
string s = "29";
var buffer = new byte[s.Length];
for (int i = 0; i < buffer.Length; i++) {
buffer[i] = (byte)(s[i] - '0');
}
Explanation:
We create a byte buffer with the same length as the input string since every character in the string is supposed to be a decimal digit.
In C#, a character is a numeric type. We subtract the character '0' from the character representing our digit to get its numeric value. We get this digit by using the String indexer which allows us to access single characters in a string.
The result is an integer that we cast to byte we can then insert into the buffer.
Console.WriteLine(buffer[0]) prints 2 because numbers are converted to a string in a decimal format for display. Everything the debugger, the console or a textbox displays is always a string the data has been converted to. This conversion is called formatting. Therefore, you do not see the result as binary. But believe me, it is stored in the bytes in the requested binary format.
You can use Convert.ToString and specify the desired numeric base as second parameter to see the result in binary.
foreach (byte b in buffer) {
Console.WriteLine($"{b} --> {Convert.ToString(b, toBase: 2).PadLeft(4, '0')}");
}
If you want to store it in this visual binary format, then you must store it in a string array
var stringBuffer = new string[s.Length];
for (int i = 0; i < stringBuffer.Length; i++) {
stringBuffer[i] = Convert.ToString(s[i] - '0', toBase: 2).PadLeft(4, '0');
}
Note that everything is stored in a binary format with 0s and 1s in a computer, but you never see these 0s and 1s directly. What you see is always an image on your screen. And this image was created from images of characters in a specific font. And these characters result from converting some data into a string, i.e., from formatting your data. The same data might look different on PCs using a different culture, but the underlying data is stored with the same pattern of 0s and 1s.
The difference between storing the numeric value of the digit as byte and storing this digit as character (possibly being an element of a string) is that a different encoding is used.
The byte stores it as a binary number equivalent to the decimal number. I.e., 9 (decimal) becomes 00001001 (binary).
The string or character stores the digit using the UTF-16 character table in .NET. This table is equivalent to the ASCII table for Latin letters without accents or umlauts, for digits and for the most common punctuation, except that it uses 16 bits per character instead of 7 bits (expanded to 8 when stored as byte). According to this table, the character '9' is represented by the binary 00111001 (decimal 57).
The string "1001" is stored in UTF-16 as
00000000 00110001 00000000 00110000 00000000 00110000 00000000 00110001
where 0 is encoded as 00000000 00110000 (decimal 48) and 1 is encoded as 00000000 00110001 (decimal 49). Also, additional data is stored for a string, as its length, a NUL character terminator and data related to its class nature.
Alternative ways to store the result would be to use an array of the BitArray Class or to use an array of array of bytes where each byte in the inner array would store one bit only, i.e., be either 0 or 1.

Cast string to hex byte array [duplicate]

This question already has answers here:
How do you convert a byte array to a hexadecimal string, and vice versa?
(53 answers)
Converting string to byte array in C#
(20 answers)
Closed 2 years ago.
I need to cast a string to a byte array in hex representation.
For example:
Value: 06000002
What I need is:
30 36 30 30 30 30 30 32
I tried to implicit convert all chars to byte as following:
byte[] bytes = new byte[daten.Length];
for (int i = 0; i < daten.Length; i++)
{
int value = Convert.ToInt32(daten[i]);
bytes[i] = (byte)daten[i];
}
However I always get this result:
48 54 48 48 48 48 48 50
I do not need the result as string! I need it as byte array!
How do achive this?
All you should need is:
var value = "06000002";
byte[] bytes = Encoding.UTF8.GetBytes(value);
In .NET 5 you can then use
string hexString = Convert.ToHexString(bytes);
To verify your result is what you expected
3036303030303032
https://dotnetfiddle.net/6sUmgE
To get the desired output, you can convert each character to its hex representation:
var s = "06000002";
var bytes = s.Select(c => (byte) c);
var hexCodes = bytes.Select(b => b.ToString("X2"));
You could stop here, or perhaps convert it to an Array or List.
Note that bytes are just numbers, there is no such thing as "hex bytes". The only time where "hex" exists is after conversion to string format, as I did above.
To still get it as one string you can proceed with this:
var result = string.Join(' ', hexCodes);
Or all in one go:
var result = string.Join(' ', "06000002".Select(c => ((byte) c).ToString("X2")));

String to byte hex convert

I would like to ask a question about string convert to byte from windows form, i have try several ways to do these, while convert string to hex is successful turn to string but the problem i need to turn it back to hex byte because the API only get bytes.
Here is the convert below:
string getTxtString = txtString.text;
int convertToInt = int32.Parse(getTxtString);
string hexString = convertToInt.toString("X");
// i have try with X2 it will get two digit for example 0A
How to convert to Hex byte in situation like this or please provide other solution.
For example:
11 = 0A
0A is the conversion of below:
int convertToInt = int32.Parse(getTxtString);
string hexString = convertToInt.toString("X2");
From the convert above will only get 0A.
The Api need to whole Hex value like 0x0A, i need to send 0x0A to API.
Try Convert.ToByte while providing fromBase (16 in your case)
// "0A" (string) -> 0x0A == 10 == 0b00001010 (byte)
byte result = Convert.ToByte(hexString, 16);
...
SomeApiMethod(..., result, ...);
In case you have a Int32 encoded in fact (e.g. "FF120A") and you want to get the last byte:
// "FF120A" (or "0xFF120A") -> 0xFF120A (int) -> 0x0A (byte)
// unchecked - we don't want OverflowException on integer overflow
byte result = unchecked((byte)Convert.ToInt32(hexString, 16));
...
SomeApiMethod(..., result, ...);
Please, notice that the byte (e.g. 0x0A) is always the same, it its string representation that can vary:
// 00001010 - binary
Console.WriteLine(Convert.ToString(result, 2).PadLeft(8, '0'));
// 10 - decimal
Console.WriteLine(result);
// 0A - hexadecimal
Console.WriteLine(result.ToString("X2"));

Conversion from Base 64 error

I'm trying to convert from a Base64 string. First I tried this:
string a = "BTQmJiI6JzFkZ2ZhY";
byte[] b = Convert.FromBase64String(a);
string c = System.Text.Encoding.ASCII.GetString(b);
Then got the exception - System.FormatException was caught Message=Invalid length for a Base-64 char array.
So after googling,I tried this:
string a1 = "BTQmJiI6JzFkZ2ZhY";
int mod4 = a1.Length % 4;
if (mod4 > 0)
{
a1 += new string('=', 4 - mod4);
}
byte[] b1 = Convert.FromBase64String(a1);
string c1 = System.Text.Encoding.ASCII.GetString(b1);
Here I got the exception - System.FormatException was caught Message=Invalid character in a Base-64 string.
Is there any invalid character in "BTQmJiI6JzFkZ2ZhY"? Or is it the length issue?
EDIT: I first decrypt the input string using the below code:
string sourstr, deststr,strchar;
int strlen;
decimal ascvalue, ConvValue;
deststr = "";
sourstr = "InputString";
strlen = sourstr.Length;
for (int intI = 0; intI <= strlen - 1; intI++)
{
strchar = sourstr.Substring(intI, 1);
ascvalue = (decimal)strchar[0];
ConvValue = (decimal)((int)ascvalue ^ 85);
if ((char)ConvValue.ToString().Length == 0)
{
deststr = deststr + strchar;
}
else
{
deststr = deststr + (char)ConvValue;
}
}
This output deststr is passed to below code
Convert.ToBase64String(System.Text.Encoding.ASCII.GetBytes(deststr));
This is where I got "BTQmJiI6JzFkZ2ZhY"
You cannot get such base64 string by encoding whole number of bytes. While encoding, every 3 bytes are represented as 4 characters, because 3 bytes is 24 bits, and each base64 character is 6 bits (2^6=64), so 4 of them is also 24 bits. If number of bytes to encode is not divisable by 3 - you have some bytes left. You can have 2 or 1 bytes left.
If you have 2 bytes left - that's 16 bits and you need at least 3 characters to encode that (2 characters is just 12 bits - not enough). So in case you have 2 bytes left - you encode them with 3 characters and apply "=" padding.
If you have 1 byte left - that's 8 bits. You need at least 2 characters for that. You encode to 2 characters and apply "==" padding.
Note that there is no way to encode something to just one character (and for that reason - there is no "===" padding).
Your string can be divided in 4 character blocks: "BTQm", "JiI6", "JzFk", "Z2Zh", "Y". 4 first blocks each represent 3 bytes, but what "Y" represents? Who knows. You can say that it represents 1 byte in range 0-63, but from above you can see that's not how it works, so to interpret it like that you have to do it yourself.
From above you can see that you cannot get base64 string with length 17 (without padding). You can get 16, 18, 19, 20, but never 17
Are you sure you took all chars from base64 output?
Appending "==" at the end of the string will make your first approach work without any problems. Although there is strange character at the beginning of the output. So the next question is: Are you sure it is "ASCI" Encoding?

Using an int as the numerical representation of a string in C#

I'm trying to use an integer as the numerical representation of a string, for example, storing "ABCD" as 0x41424344. However, when it comes to output, I've got to convert the integer back into 4 ASCII characters. Right now, I'm using bit shifts and masking, as follows:
int value = 0x41424344;
string s = new string (
new char [] {
(char)(value >> 24),
(char)(value >> 16 & 0xFF),
(char)(value >> 8 & 0xFF),
(char)(value & 0xFF) });
Is there a cleaner way to do this? I've tried various casts, but the compiler, as expected, complained about it.
Characters are 16 bit, so you have to encode them into eight bit values to pack them in an integer. You can use the Encoding class to convert between characters and bytes, and the BitConverter class to convert between bytes and integer
Here is conversion both ways:
string original = "ABCD";
int number = BitConverter.ToInt32(Encoding.ASCII.GetBytes(original), 0);
string decoded = Encoding.ASCII.GetString(BitConverter.GetBytes(number));
Note that the order of the bytes in the integer depends on the endianess of the computer. On a little endian system the numeric value of "ABCD" will be 0x44434241. To get the reverse order, you can reverse the byte array:
byte[] data = Encoding.ASCII.GetBytes(original);
Array.Reverse(data);
int number = BitConverter.ToInt32(data, 0);
byte[] data2 = BitConverter.GetBytes(number);
Array.Reverse(data2);
string decoded = Encoding.ASCII.GetString(data2);
Or if you are using framework 3.5:
int number =
BitConverter.ToInt32(Encoding.ASCII.GetBytes(original).Reverse().ToArray() , 0);
string decoded =
Encoding.ASCII.GetString(BitConverter.GetBytes(number).Reverse().ToArray());
int value = 0x41424344;
string s = Encoding.ASCII.GetString(
BitConverter.GetBytes(value).Reverse().ToArray());
(The above assumes that you're running on a little-endian system. For big-endian you could just drop the .Reverse().ToArray() part, although if you are on a little-endian system then it would probably make more sense for you to just store "ABCD" as 0x44434241 in the first place, if possible.)
public string ConvertToHex(string asciiString)
{
string hex = "";
foreach (char c in asciiString)
{
int tmp = c;
hex += String.Format("{0:x2}", (uint)System.Convert.ToUInt32(tmp.ToString()));
}
return hex;
}
It will convert string to hex as you required.
public static string ToHexString(string value)
{
return value.Aggregate(new StringBuilder("0x"),
(sb, c) => sb.AppendFormat("{0:x2}", (int)c)).ToString();
}
if the string is never longer than 8 chars and a kind of Hexstring, you could use
the base variable 16 have a look at the Conversion functions from the Convert class.
string s = "ABCD";
uint i = Convert.ToUInt32( s, 16 );
MessageBox.Show( Convert.ToString( i, 16 ) );
regards
Oops

Categories