Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why Encoding.Default.GetBytes() returns different results in VB.NET and C#?

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.

like image 725
Annagram Avatar asked May 29 '09 19:05

Annagram


People also ask

What does encoding ascii getBytes do?

GetBytes(Char*, Int32, Byte*, Int32)Encodes a set of characters starting at the specified character pointer into a sequence of bytes that are stored starting at the specified byte pointer.

Which method encodes a string into a sequence of bytes?

The Java String getBytes() method encodes the string into a sequence of bytes and stores it in a byte array. Here, string is an object of the String class. The getBytes() method returns a byte array.

What is System text encoding?

Encoding is the process of transforming a set of Unicode characters into a sequence of bytes. In contrast, decoding is the process of transforming a sequence of encoded bytes into a set of Unicode characters.


2 Answers

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

like image 66
RichardOD Avatar answered Sep 27 '22 16:09

RichardOD


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]);
like image 38
Joe Avatar answered Sep 27 '22 17:09

Joe