2012-08-26 52 views
5

Tôi đang cố gắng tạo một chuỗi ngẫu nhiên trong .NET và chuyển đổi thành byte và gặp sự cố nhỏ. Tôi muốn tập hợp đầy đủ các ký tự có thể, và sự hiểu biết của tôi là một chuỗi có thể chứa bất kỳ ký tự nào.Tạo chuỗi ngẫu nhiên

Mã của tôi hiện nay là như sau:

var plainText = new StringBuilder(); 
for (int j = 0; j < stringLength; ++j) 
{ 
    plainText.Append((char)_random.Next(char.MinValue, char.MaxValue)); 
} 
byte[] x = Encoding.Unicode.GetBytes(plainText.ToString()); 
string result = Encoding.Unicode.GetString(x); 

Về lý thuyết, plainTextresult nên giống hệt nhau. Chúng hầu như giống nhau, nhưng một số ký tự ban đầu bị mất, dường như là các ký tự trong phạm vi 55000-57000 - chúng được thay thế bằng ký tự 65533.

Tôi giả định vấn đề là với mã hóa của tôi, nhưng tôi nghĩ Unicode sẽ xử lý điều này đúng cách. Tôi đã thử UTF8 và UTF32, nhưng những người cho tôi cùng một vấn đề.

Mọi suy nghĩ?

+0

lạ ?! unicode có thể được, nhưng khi bạn thử nghiệm nó với utf-32 ?! – TheHe

+1

Bạn đang cố gắng đạt được điều gì? – CodesInChaos

+0

Tôi giả sử bạn đang sản xuất một chuỗi UTF-16 không hợp lệ với các ký tự đại diện chưa được ghép nối. – CodesInChaos

Trả lời

8

Vấn đề là các ký tự trong phạm vi 0xD800-0xDFFF (55296-57343), được gọi là các ký tự thay thế Unicode, không hợp lệ theo cách riêng của chúng. Chúng phải xuất hiện dưới dạng một cặp (0xD800-0xDBFF đầu tiên, 0xDC00-0xDFFF giây) để hợp lệ (trong lược đồ mã hóa UTF-16). Một mình, chúng sẽ được coi là ký tự không hợp lệ và được giải mã thành 0xFFFD (65533). C# sử dụng UTF-16 để biểu diễn các chuỗi của nó, vì vậy đó là lý do tại sao bạn thấy đầu ra đó.

Bạn có thể chọn lọc chúng ra (ví dụ: gọi _random.Next cho đến khi bạn nhận được ký tự không thay thế) hoặc tạo cặp thay thế hợp pháp bất cứ khi nào bạn tạo ký tự thay thế.

+0

Tuyệt vời, cảm ơn. Tôi đã không xử lý các nhân vật thay thế trước đây. –

2

Đó là các ký tự thay thế 55296-57343 (0xD800-0xDFFF). Bạn cần ghép nối chúng một cách chính xác. Một cặp ký tự thay thế trong UTF-16 mô tả một điểm mã đơn unicode.

Bạn dường như hoạt động dựa trên giả định rằng char và điểm mã là giống nhau. Điều đó không đúng, có> 2^16 mã-điểm.

Tôi khuyên bạn nên đọc UTF-16 Wikipedia Article.