I'm trying to convert the string "Eureka" into its UTF-8 Int64 representation.
I'm trying the following code :
string message = "Eureka"; // if I use "Eureka\0\0" it works...
byte[] bytes = System.Text.Encoding.UTF8.GetBytes(message);
// this fails because I have 6 bytes, not 8 (as required for Int64)
Int64 m = BitConverter.ToInt64(bytes, 0);
byte[] decodeBites = BitConverter.GetBytes(m);
string decodeMessage = System.Text.Encoding.UTF8.GetString(decodeBites);
if (!decodeMessage.Equals(message)) {
Console.WriteLine("Message mis-match!!!");
}
Now, because my string is too short, I don't have the right number of bytes and it fails. If I add 2 chars, it works, but then I don't have the desired string in decodeMessage... Pretty sure I need some conversion trick to remove the trailing "0" bytes after the conversion, but none of my attempts work. Any help would be much appreciated!!
UPDATE
The goal is REALLY to have the integer representation of "Euraka", not "Eureka\0\0" then trim at the end.... The goals is to use the RSA-method on the obtained Int64, so at the other end, people won't know they have to trim anything...!
Let's pad the array with 0 (to ensure the array contain of 8 bytes) and trim the string from \0:
string message = "Eureka"; // if I use "Eureka\0\0" it works...
byte[] bytes = System.Text.Encoding.UTF8.GetBytes(message);
byte[] pad = new byte[bytes.Length < sizeof(Int64) ? sizeof(Int64) - bytes.Length : 0];
// Concat(new byte[...]) - ensure m contains 8 bytes
Int64 m = BitConverter.ToInt64(
bytes.Concat(pad).ToArray(),
0);
byte[] decodeBites = BitConverter.GetBytes(m);
// Since we have 8 bytes always, we have to get rid of tail '\0'
string decodeMessage = System.Text.Encoding.UTF8.GetString(decodeBites).TrimEnd('\0');
if (!decodeMessage.Equals(message)) {
Console.WriteLine("Message mis-match!!!");
}
Edit: Since Int64 has 8 and "Eureka" is encoded in 6 only, will-nilly you have to get rid of 2 zero bytes. If you don't want Trim you can Skip them e.g.
byte[] decodeBites = BitConverter
.GetBytes(m)
.TakeWhile(b => b != 0)
.ToArray();
string decodeMessage = System.Text.Encoding.UTF8.GetString(decodeBites);
Related
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.
I have one column in DB containing UTF16 string and I want to convert the UTF16 string into normal text. How to achieve this in c# ?
For example :
Source : 0645 0631 062D 0628 0627 0020 0627 0644 0639 0627 0644 0645
Convert : مرحبا العالم
I presume that source is simply a string containing the byte values, as this is one thing not quite clear from your question.
You first need to turn that into a byte array. Of course you first need to remove the blanks.
// Initialize the byte array
string sourceNoBlanks = source.Replace(" ", "").Trim();
if ((sourceNoBlanks.Length % 2) > 0)
throw new ArgumentException("The length of the source string must be a multiple of 2!");
byte[] sourceBytes = new byte[source.Length / 2];
// Then, create the bytes
for (int i = 0; i < sourceBytes.Length; i++)
{
string byteString = sourceNoBlanks.Substring(i*2, 2);
sourceBytes[i] = Byte.Parse(byteString, NumberStyles.HexNumber);
}
After that you can easily convert it to string:
string result = Encoding.UTF32.GetString(sourceBytes);
I suggest you read up on the UTF32 encoding to understand little/big endian encoding.
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;
}
I am reading information from a device and it's returning data to me in integer format and I need to convert this to ASCII characters using C#.
The following is an example of the data I have to convert. I receive the integer value 26990 back from my device and I need to convert that to ASCII. I just happen to know that for this value, the desired result would be "ni".
I know that the integer value 26990 is equal to 696e in hex, and 110100101101110 in binary, but would like to know how to do the conversion as I can't work it out for myself.
Can anyone help please?
Many thanks,
Karl
int i = 26990;
char c1 = (char)(i & 0xff);
char c2 = (char)(i >> 8);
Console.WriteLine("{0}{1}", c1, c2);
Use BitConverter and Encoding to perform the conversion:
class Program
{
public static void Main()
{
int d = 26990;
byte[] bytes = BitConverter.GetBytes(d);
string s = System.Text.Encoding.ASCII.GetString(bytes);
// note that s will contain extra NULLs here so..
s = s.TrimEnd('\0');
}
}
If the device is sending bytes you can use something like this:
byte[] bytes = new byte[] { 0x69, 0x6e };
string text = System.Text.Encoding.ASCII.GetString(bytes);
Otherwise, if the device is sending integers you can use something like this:
byte[] bytes = BitConverter.GetBytes(26990);
string text = System.Text.Encoding.ASCII.GetString(bytes, 0, 2);
In either case, text will contain "ni" after that executes. Note that in the latter you may have to deal with endianness issues.
Further reference:
Encoding class
Encoding.ASCII property
Encoding.GetString method overloads
I'm working with C# trying to convert a string value into a byte. Seems to be harder then I expected. Basically I have a string called hex = "0x32" and need byte block to equal this value.
string hex = "0x32";
byte block = Convert.ToByte(hex);
The above doesn't work, does anybody know how I can successfully assign the hex value to the byte. I need to append this byte to a byte array later in the code.
Try the following
byte block = Byte.Parse(hex.SubString(2), NumberStyles.HexNumber);
The reason for the SubString call is to remove the preceeding "0x" from the string. The Parse function does not expect the "0x" prefix even when NumberStyles.HexNumber is specified and will error if encountered
Convert.ToByte(hex, 16)
string hex = "0x32";
int value = Convert.ToInt32(hex, 16);
byte byteVal = Convert.ToByte(value);
Will work...
Edit
A little code to demonstrate that 0x32 (hex) and 50 (int) are the same.
string hex = "0x32";
byte[] byteVal = new byte[1];
byteVal[0] = Convert.Byte(hex, 16);
Console.WriteLine(byteVal[0] + " - Integer value");
Console.WriteLine(BitConverter.ToString(byteVal) + " - BitArray representation");;