2009-05-29 47 views
6

Gần đây chúng tôi đã xem một số mã mẫu từ một nhà cung cấp để băm khóa bí mật cho cuộc gọi dịch vụ web, mẫu của họ là trong VB.NET mà chúng tôi đã chuyển đổi thành C#. Điều này gây ra băm để tạo ra đầu vào khác nhau. Nó chỉ ra cách họ đã tạo ra chìa khóa cho việc mã hóa bằng cách chuyển đổi một mảng char thành một chuỗi và trở lại một mảng byte. Điều này dẫn tôi đến khám phá rằng VB.NET và bộ mã hóa mặc định của C# hoạt động khác với một số ký tự.Tại sao Encoding.Default.GetBytes() trả về các kết quả khác nhau trong VB.NET và C#?

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)) 

C# đầu ra là 63, trong khi VB là giá trị byte đúng 149. nếu bạn sử dụng bất kỳ giá trị khác, như 145, vv , kết quả đầu ra phù hợp.

Đi bộ qua gỡ lỗi, cả bộ mã hóa mặc định VB và C# là SBCSCodePageEncoding.

Có ai biết tại sao điều này không?

Tôi đã sửa mã mẫu bằng cách trực tiếp khởi tạo một mảng byte, mà nó phải có ở vị trí đầu tiên, nhưng tôi vẫn muốn biết lý do tại sao bộ mã hóa không phải là ngôn ngữ cụ thể, có vẻ như vậy.

Trả lời

11

Nếu bạn sử dụng ChrW (149), bạn sẽ nhận được kết quả khác nhau- 63, giống như C#.

Dim b As Char() = {ChrW(149)} 
Console.WriteLine(Encoding.Default.GetBytes(b)(0)) 

đọc the documentation để xem difference- rằng sẽ giải thích câu trả lời

+2

Dưới đây là một liên kết đến tài liệu: http://msdn.microsoft .com/vi-us/library/613dxh46 (VS.80) .aspx –

+0

Chúc mừng Jon- Tôi chỉ đang trong quá trình thêm liên kết. – RichardOD

+0

Cảm ơn! Tôi đã nghĩ rằng nó có một cái gì đó để làm với Chr() bit, nhưng tôi đã không chắc chắn làm thế nào để tránh sử dụng Chr() trong VB.NET. – Annagram

0

default encoding phụ thuộc vào máy cũng như chủ đề phụ thuộc vì nó sử dụng bảng mã hiện tại. Bạn thường nên sử dụng một cái gì đó như Encoding.UTF8 để bạn không phải lo lắng về những gì sẽ xảy ra khi một máy đang sử dụng unicode và một máy khác đang sử dụng 1252-ANSI.

0

Hệ điều hành khác nhau có thể sử dụng các mã hóa khác nhau làm mặc định. Do đó, dữ liệu được truyền từ một hệ thống điều hành sang hệ điều hành khác có thể là được dịch không chính xác. Để đảm bảo rằng byte được mã hóa được giải mã đúng cách, ứng dụng của bạn nên sử dụng mã hóa Unicode, nghĩa là, UTF8Encoding, UnicodeEncoding hoặc UTF32Encoding, với lời mở đầu. Một tùy chọn khác là sử dụng giao thức cấp cao hơn để đảm bảo rằng cùng một định dạng được sử dụng để mã hóa và giải mã.

từ http://msdn.microsoft.com/en-us/library/system.text.encoding.default.aspx

bạn có thể kiểm tra những gì mỗi ngôn ngữ tạo ra khi bạn rõ ràng mã hóa sử dụng utf8?

4

Chức năng VB Chr có một đối số trong khoảng từ 0 đến 255, và chuyển đổi nó vào một nhân vật bằng cách sử dụng trang mã mặc định hiện tại. Nó sẽ ném một ngoại lệ nếu bạn vượt qua một đối số bên ngoài phạm vi này.

ChrW sẽ lấy giá trị 16 bit và trả về Hệ thống tương ứng.Giá trị Char không sử dụng mã hóa - do đó sẽ cho kết quả tương tự như mã C# bạn đã đăng.

Tương đương gần đúng của mã VB của bạn trong C# mà không sử dụng các lớp VB Strings (đó là lớp chứa Chr và ChrW) sẽ là:

char[] chars = Encoding.Default.GetChars(new byte[] { 149 }); 
Console.Write(Encoding.Default.GetBytes(chars)[0]); 
0

Tôi tin rằng tương đương trong VB là ChrW (149) .

Vì vậy, mã VB này ...

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))) 

sẽ cho kết quả tương tự như mã này # C ...

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]); 
Các vấn đề liên quan