Convert a Binary String longer than 8 into a single unicode character - c#

I need to convert a string into binary and back.
But when the input is an Unicode Character the resulting Binary String is longer than 8 characters and converting it back using Convert.ToByte causes an Overflow Exception.
I used the Convert.ToString method to convert the String into Binary.
String input = "⌓" //Unicode Character
String binary = Convert.ToString(input, 2); //Convert to Binary
//->> Returns "10001100010011"
byte re = Convert.ToByte("10001100010011", 2); //This causes an Overflow Exception
//What should I do here? Is there a better reverse of Convert.ToString than Convert.ToByte?
Is there an alternative or something similar?

I think the problem here is that a byte is only 8 bits. You are putting in a string with 14 bits in it. Try using Convert.ToUint16() and declare "re" as Uint16 like so:
UInt16 re = Convert.ToUInt16("10001100010011", 2);
// UInt16 is large enough to hold the data
Console.WriteLine(re); // prints 8979
//unicode decimal 8979: http://www.codetable.net/decimal/8979

Related

C# utf8-encoding bytearray out of range

I have the following problem: if the String contains a char that is not known from ASCII, it uses a 63.
Because of that i changed the encoding to UTF8, but I know a char can have the length of two bytes, so I get a out of range error.
How can I solve the problem?
System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
byte[] baInput = enc.GetBytes(strInput);
// Split byte array (6 Byte) in date (days) and time (ms) parts
byte[] baMsec = new byte[4];
byte[] baDays = new byte[2];
for (int i = 0; i < baInput.Length; i++)
{
if (4 > i)
{
baMsec[i] = baInput[i];
}
else
{
baDays[i - 4] = baInput[i];
}
}
The problem you seem to be having is that you know the number of characters, but not the number of bytes, when using UTF8. To solve just that problem, you could use:
byte[] baMsec = Encoding.UTF8.GetBytes(strInput.SubString(0, 4));
byte[] baDays = Encoding.UTF8.GetBytes(strInput.SubString(4));
Recommended Solution:
1) Split the strInput using the SubString(Int32, Int32) method and get the date and time parts in separate String variables, say strDate and strTime.
2) Then call UTF8Encoding.GetBytes on strDate and strTime and collect the byte array in baDays and baMsec respectively.
Why this works:
C# String is by default UTF-16 encoded, which is equally good to represent non-ASCII characters. Hence, no data is lost.
General Caution:
Never try to directly manipulate encoded strings at byte-level, you'll get lost. Use the String and Encoding class methods of C# to get the bytes if you want bytes.
Alternate approach:
I'm wondering (like others) why your date-time data contains non-numeric characters. I saw in a comment that you get your data from reader["TIMESTAMP2"].ToString(); and the sample content is §║ ê or l¦h. Check if you are interpreting numeric data stored in reader["TIMESTAMP2"] as String by mistake and should you actually treat it as a numeric type. Otherwise, even with this method, you'll be getting unexpected output soon.
The problem is that your baInput can contain more values than both baDays and baMsec can contain. After 6 iterations, you run out of the array size. Hence, the exception.
When you hit the seventh iteration, you get i - 4 which yields 6 - 4 = 2.
Since baDays only has two items, you can set the values on index 0 and 1.

Passing a hex string in a textbox.text property to BitConverter.GetBytes as hex in C#

I am reading values from sensors and receiving two 16 bit Hex values back in string format "417D" and "8380" for example.
I cannot seem to find a way in C# to parse the strings to split them up into a byte array ( 41,7D,83,80 ) preserving the hex number.
I then use the following to convert the IEEE754 number to a decimal to get the correct sensor reading value.
txtFloatValue.Text = BitConverter.ToSingle(hex, 0).ToString();
The code below works, but I need to pass the values as a hex array, not 0x417D8380.
byte[] hex = BitConverter.GetBytes(0x417D8380);
txtFloatValue.Text = BitConverter.ToSingle(hex, 0).ToString();
Any advice would be much appreciated. I may be approaching this the wrong way, but the IEEE754 conversion works well.
You can parse your hex strings to ints and then use BitConverter. For example:
var i = int.Parse("417D8380", NumberStyles.AllowHexSpecifier);
var bytes = BitConverter.GetBytes(i);
var single = BitConverter.ToSingle(bytes, 0); // 15.8446

Converting from System.String to Sytstem.byte while reading from MYSQL

I have a BLOB file which Im reading from database. Following is the code:
byte[] bytes;
sdr.Read();
bytes = (byte[])sdr["proposalDoc"];
But the below exception occurs:
"unable to convert from system.string to system.byte"
I wrote the following before noticing your clarification that the value returned as a string is really just a binary blob. If that's correct, than the link provided by the other commenters looks like what you need. But if the "blob" is actually a series of ASCII characters transformed to Unicode (or a stream of bytes where each byte was transformed into a word by setting the high order byte to 0), then something like the following would apply.
Assuming that the field returned by sdr["proposalDoc"] is really just an ASCII string converted to Unicode, and that all you're trying to do is reconstruct the ASCII byte string (nul-terminated), you could do something like the following. (Note, there may be more optimal ways of doing this, but this could get you started.)
// Get record field.
string tempString = sdr["proposalDoc"];
// Create byte array to hold one ASCII character per Unicode character
// in the field, plus a terminating nul.
bytes = new byte[tempString.Length + 1];
// Copy each character from the field to the byte array,
// keeping the low byte of the character.
int i = 0;
foreach (char c in tempString)
{
bytes[i++] = (byte)c;
}
// Store the terminating nul character, assuming a
// nul-terminated ASCII string is the desired outcome.
bytes[i]=0;

convert hex to byte without conversion

I have a very specific requirement. I have some data. Of which, strings and spaces are to be converted to EBCDIC while numbers to Hexadecimal.
For Example, my string is "Test123"
Test => EBCDIC
123 => Hexadecimal.
What I am trying to do is check every character in string if its number or not, and then based on that doing my conversion.
byte[] dataBuffer = new byte[length];
int i = 0;
if (toEBCDIC)
{
foreach (char c in data)
{
byte[] temp = new byte[1];
if (Char.IsNumber(c))
{
string hexValue = Convert.ToInt32(c).ToString("X");
temp = Encoding.ASCII.GetBytes(hexValue);
dataBuffer[i] = temp[0];
}
else
{
temp = Encoding.GetEncoding("IBM01140").GetBytes(c.ToString());
dataBuffer[i] = temp[0];
}
i++;
}
dataBuffer.CopyTo(array, byteIndex);
The problem comes when i try to convert the number. I need to keep my output in byte array, as i have to write the output to a memory stream and then to a file.
When i get the hex value of number, and then try to convert it to byte, actual conversion happens.
For "1", hexvalue = 31.
Now I want to keep this 31 unchanged in bytes. I mean to say that, when i write it to byte array, it should remain 31 only. But when do GetBytes, it makes byte array, converting 3 and 1 separately to bytes.
Can anyone please help me on this..!!
The problem is here:
ToString("X")
Now it's a hexadecimal string. So in your example, from this point onward, the 3 and the 1 have become separated.
How to fix this: don't convert.
if (Char.IsNumber(c))
{
dataBuffer[i] = (byte)c;
}
Not tested. I think that's what you want. At least, that's what you describe in the last paragraph. That wouldn't make the numbers hexadecimal though - it would make them ASCII, and it's a bit odd to be mixing that with EBCDIC.
You convert the char to its code and then convert that code to string. You don't have to do the second step, instead use the code directly:
if (Char.IsNumber(c))
{
byte hexValue = Convert.ToByte(c);
dataBuffer[i] = hexValue;
}

C# Convert Char to Byte (Hex representation)

This seems to be an easy problem but i can't figure out.
I need to convert this character < in byte(hex representation), but if i use
byte b = Convert.ToByte('<');
i get 60 (decimal representation) instead of 3c.
60 == 0x3C.
You already have your correct answer but you're looking at it in the wrong way.
0x is the hexadecimal prefix
3C is 3 x 16 + 12
You could use the BitConverter.ToString method to convert a byte array to hexadecimal string:
string hex = BitConverter.ToString(new byte[] { Convert.ToByte('<') });
or simply:
string hex = Convert.ToByte('<').ToString("x2");
char ch2 = 'Z';
Console.Write("{0:X} ", Convert.ToUInt32(ch2));
get 60 (decimal representation) instead of 3c.
No, you don't get any representation. You get a byte containing the value 60/3c in some internal representation. When you look at it, i.e., when you convert it to a string (explicitly with ToString() or implicitly), you get the decimal representation 60.
Thus, you have to make sure that you explicitly convert the byte to string, specifying the base you want. ToString("x"), for example will convert a number into a hexadecimal representation:
byte b = Convert.ToByte('<');
String hex = b.ToString("x");
You want to convert the numeric value to hex using ToString("x"):
string asHex = b.ToString("x");
However, be aware that you code to convert the "<" character to a byte will work for that particular character, but it won't work for non-ANSI characters (that won't fit in a byte).

Categories

Resources