I have written a piece of code which returns byte code of any character which is shown below
string ByteCodeValue = Convert.ToString((char)65533, 2).PadLeft(8, '0');
//which returns value "1111111111111101"
but when i try to do it vice-versa it does not work and gives an exception as follows "Value was either too large or too small for an unsigned byte."
char OldChar= (char)Convert.ToByte("1111111111111101", 2);
Please tell me where i am going wrong?
Thanks in advance
You're converting 16-bit unsigned value, not byte (8 bit). See this doc. Try using:
var oldChar = (char)Convert.ToUInt16(ByteCodeValue,2);
Related
I got a MAC address as a hex string "0009A8040060" and I want to covert the last 3 bytes to int. Then I want to covert it back. I've thought I understood the basics with hex conversion - but apparently not!
My attempt thus far is
string endSerial = "0009A8040060".Substring(6);
int key = Convert.ToInt32(endSerial, 16);
Key is after that 262240. This seems to be correct, but when I convert it using the code run on the server (which I cannot change)
int key = x; // receives over tcp. I´ve logged this int and its transferred ok!
string endSerial = BitConverter.ToString(BitConverter.GetBytes(Convert.ToUInt32(key))).Replace("-", "");
This gives endSerial = 60000400.
I want it to be 00040060. There seems to be some kind of reverse-issue? BitConverter.IsLittleEndian is always true though.
Please help
Normally, you wouldn't use BitConverter, and would just do:
key.ToString("X6");
However, apparently you can't change the BitConverter code, so that's not an option.
BitConveter, as you have discovered, is outputting the bytes in little endian - the least significant byte first. However, when you are converting the string "040060" using Convert.ToInt32, it can be thought of as using big endian - the first byte 04 is being treated as the most significant byte. This is because Convert.ToInt32 is designed to parse numbers written in the "everyday life" way, and big endian is how we write numbers in our everyday life. We write the most significant digit first.
Therefore, one way to fix this would be to switch the byte order of key before you send it:
int key = Convert.ToInt32(endSerial, 16);
byte[] bytes = BitConverter.GetBytes(key);
Array.Reverse(bytes);
key = BitConverter.ToInt32(bytes, 0); // now it's in the right order!
I have no knowledge of C++ and I have to cenvert some code to C#. I've managed to do some bits but I don't really understand how to convert a few lines so I'm here asking for help.
This is the C++ code:
WCHAR wsSerial[MAX_PATH]={'\0'};
WCHAR wsS2[MAX_PATH]={'\0'};
wcscpy_s(wsSerial, MAX_PATH, m_strSerial);
wcscpy_s(wsS2,MAX_PATH,wsSerial+8);
wsS2[8]=NULL;
ULONG ulCode2 = wcstoul(wsS2, NULL,10);
This is what I have in C#:
string wsSerial;
string wsS2;
wsSerial = mSerial; //an external input
wsS2 = wsSerial + 8;
wsS2= wsSerial.Substring(0, 8);
long ulCode2 = long.Parse(wsS2);
So I have two questions:
wsSerial is an array in C++ but I don't need an array for this in C#, do I? I mean, all it does is store a large number which is later converted into a numeric value, right?
What exactly does this do? wcscpy_s(wsS2,MAX_PATH,wsSerial+8). The + 8 throws me off.
In C a string is simply a contiguous area containing a "string" of characters, terminated by a special character. In other words, an array of char. (Or wchar_t for wide-character strings.)
In C# (and C++) this is not needed as it has its own special string type, which handles the array-stuff behind the scenes.
Regarding the +8 thing, it simply skips the first eight characters of wsSerial when copying. To understand this, you should read about "pointer arithmetic".
It's like this:
string wsSerial = mSerial;
string wsS2 = wsSerial.Substring(8, 8);
long ulCode2 = long.Parse(wsS2);
It looks like you're almost all the way there, but the first argument in the call to
wsSerial.Substring()
should be 8, the second should be MAX_PATH minus 8.
image is the string of an image file .
I have code as follows in C#:
Convert.ToBase64String(image);
and code as follows in Java:
org.apache.commons.codec.binary.Base64.encodeBase64(image.getBytes())
The result is different.
Somebody says its because
Java byte : -128 to 127
C# byte : 0 to 255
But how can I fix this? How can I implement C#'s Convert.ToBase64String() in Java?
I need the same result as in C# by using Java.
First you need to realise that a byte stores 256 values whether its signed or unsigned. If you want to get unsigned values from a signed byte (which is what Java supports) you can use & 0xFF
e.g.
byte[] bytes = { 0, 127, -128, -1};
for(byte b: bytes) {
int unsigned = b & 0xFF;
System.out.println(unsigned);
}
prints
0
127
128
255
The simple answer is you don't need a byte[] which has the same values. ;)
You're base64 encoding a string? What do you want that to do? You first need to convert the string to a sequence of bytes, choosing an encoding such as UTF-8 or UTF-16.
My guess is that you managed to use different encodings on both sides. Java's String.GetBytes() uses the default charset (Probably something like Latin1 on western windows versions). For C# you didn't post the relevant code.
To fix this, choose an encoding and use it explicitly on both sides. I recommend using UTF-8.
On the Java side you should use the correct method for encoding, so you don't end up with "modified UTF-8", but since I'm not a java programmer, I don't know which methods output modified UTF-8. I think it only happens if you abuse some internal serialization method.
signed vs. unsigned bytes should not be relevant here. The intermediate byte buffer will be different, but the original string, and the base64 string should be identical on both sides.
I also encountered the same problem. There is a saying on the Internet:
Java byte : -128 to 127 | C# byte : 0 to 255
I looked up the algorithmic principle of java base64 encoding and decoding. Use C# to implement the base64 algorithm and run the program: the result is the same as
Convert.ToBase64String(byteArray).
Finally found that the best way to solve this problem is:
Uri.EscapeDataString(Convert.ToBase64String(byteArray)).
It should be noted that this is the reason for the special characters in the URL.
I have a VC++ character array "wchar_t arr[0x30] = { 0x0,0x1,..., 0xC...hexadecimal initialization here ......}". There is one more C++ character pointer wchar_t * xyz.
An operation something like---- wchar_t ch = arr[xyz[2]] is done.
Can someone kindly explain in detail what is happening in this, because arr[] is a char array and we should pass an integer as an index to any array right? But here the index passed to the character array "arr[] " is another character pointer xyz[2]. In the above code suppose a character 'a' is stored at xyz[2] than does it mean we are indexing a C++ character array like this--- arr[xyz[2]] becomes arr['a']. Kindly let me know.
How can I achieve this in c SHarp.. Probably if I get to know that what is happening in C++ code above I can myself achieve it in C SHarp. Can anyone kindly let me know what is happening here in this C++ code.
What happens is that the wchar_t stored at xyz[2] is promoted to an int, then used as an index into the arr array.
It also means that, if xyz[2] contains L'a', the program will exhibit undefined behavior, since arr only has space for 48 items but L'a' will be promoted to 97.
Concerning the second part of your question, C# only supports pointer arithmetic inside unsafe blocks, so you'll probably want to use arrays instead:
char[] arr = new char[0x30];
char[] xyz = Something();
char ch = arr[xyz[2]];
We recently came across some sample code from a vendor for hashing a secret key for a web service call, their sample was in VB.NET which we converted to C#. This caused the hashing to produce different input. It turns out the way they were generating the key for the encryption was by converting a char array to a string and back to a byte array. This led me to the discovery that VB.NET and C#'s default encoder work differently with some characters.
C#:
Console.Write(Encoding.Default.GetBytes(new char[] { (char)149 })[0]);
VB:
Dim b As Char() = {Chr(149)}
Console.WriteLine(Encoding.Default.GetBytes(b)(0))
The C# output is 63, while VB is the correct byte value of 149.
if you use any other value, like 145, etc, the output matches.
Walking through the debugging, both VB and C# default encoder is SBCSCodePageEncoding.
Does anyone know why this is?
I have corrected the sample code by directly initializing a byte array, which it should have been in the first place, but I still want to know why the encoder, which should not be language specific, appears to be just that.
If you use ChrW(149) you will get a different result- 63, the same as the C#.
Dim b As Char() = {ChrW(149)}
Console.WriteLine(Encoding.Default.GetBytes(b)(0))
Read the documentation to see the difference- that will explain the answer
The VB Chr function takes an argument in the range 0 to 255, and converts it to a character using the current default code page. It will throw an exception if you pass an argument outside this range.
ChrW will take a 16-bit value and return the corresponding System.Char value without using an encoding - hence will give the same result as the C# code you posted.
The approximate equivalent of your VB code in C# without using the VB Strings class (that's the class that contains Chr and ChrW) would be:
char[] chars = Encoding.Default.GetChars(new byte[] { 149 });
Console.Write(Encoding.Default.GetBytes(chars)[0]);
The default encoding is machine dependent as well as thread dependent because it uses the current codepage. You generally should use something like Encoding.UTF8 so that you don't have to worry about what happens when one machine is using unicode and another is using 1252-ANSI.
Different operating systems might use
different encodings as the default.
Therefore, data streamed from one
operating system to another might be
translated incorrectly. To ensure that
the encoded bytes are decoded
properly, your application should use
a Unicode encoding, that is,
UTF8Encoding, UnicodeEncoding, or
UTF32Encoding, with a preamble.
Another option is to use a
higher-level protocol to ensure that
the same format is used for encoding
and decoding.
from http://msdn.microsoft.com/en-us/library/system.text.encoding.default.aspx
can you check what each language produces when you explicitly encode using utf8?
I believe the equivalent in VB is ChrW(149).
So, this VB code...
Dim c As Char() = New Char() { Chr(149) }
'Dim c As Char() = New Char() { ChrW(149) }
Dim b As Byte() = System.Text.Encoding.Default.GetBytes(c)
Console.WriteLine("{0}", Convert.ToInt32(c(0)))
Console.WriteLine("{0}", CInt(b(0)))
produces the same output as this C# code...
var c = new char[] { (char)149 };
var b = System.Text.Encoding.Default.GetBytes(c);
Console.WriteLine("{0}", (int)c[0]);
Console.WriteLine("{0}", (int) b[0]);