2010-10-12 28 views
36

Tôi đã đọc về Unicode và UTF-8 trong mấy ngày vừa qua và tôi thường đi qua một so sánh Bitwise tương tự như sau:UTF-8 & Unicode, những gì có 0xC0 và 0x80?

int strlen_utf8(char *s) 
{ 
    int i = 0, j = 0; 
    while (s[i]) 
    { 
    if ((s[i] & 0xc0) != 0x80) j++; 
    i++; 
    } 
    return j; 
} 

Ai đó có thể làm rõ sự so sánh với 0xc0 và kiểm tra nếu đó là điều ý nghĩa nhất ?

Cảm ơn bạn!

EDIT: ANDed, không so sánh, sử dụng từ sai;)

Trả lời

71

Đó không phải là một sự so sánh với 0xc0, đó là một logic AND tác với 0xc0.

Các bit mặt nạ 0xc011 00 00 00 vì vậy những gì AND đang làm chỉ trích hai bit đầu:

ab cd ef gh 
AND 11 00 00 00 
    -- -- -- -- 
    = ab 00 00 00 

này sau đó được so sánh với 0x80 (nhị phân 10 00 00 00). Nói cách khác, câu lệnh if đang kiểm tra xem hai bit trên cùng của giá trị không bằng 10.

"Tại sao?", Tôi nghe bạn hỏi. Vâng, đó là một câu hỏi hay. Câu trả lời là, trong UTF-8, tất cả các byte bắt đầu với các mẫu bit 10 là byte tiếp theo của một chuỗi đa byte:

    UTF-8 
Range    Encoding Binary value 
----------------- -------- -------------------------- 
U+000000-U+00007f 0xxxxxxx 0xxxxxxx 

U+000080-U+0007ff 110yyyxx 00000yyy xxxxxxxx 
        10xxxxxx 

U+000800-U+00ffff 1110yyyy yyyyyyyy xxxxxxxx 
        10yyyyxx 
        10xxxxxx 

U+010000-U+10ffff 11110zzz 000zzzzz yyyyyyyy xxxxxxxx 
        10zzyyyy 
        10yyyyxx 
        10xxxxxx 

Vì vậy, những gì đoạn này ít được làm đang trải qua từng byte chuỗi UTF-8 của bạn và đếm tất cả các byte không phải là byte tiếp tục (nghĩa là nó nhận được độ dài của chuỗi, như được quảng cáo). Xem this wikipedia link để biết thêm chi tiết và Joel Spolsky's excellent article cho sơn lót.


Một điều thú vị nữa. Bạn có thể phân loại các byte trong một dòng UTF-8 như sau:

  • Với bit cao được đặt thành 0, nó là một giá trị byte đơn.
  • Với hai bit cao được đặt thành 10, đó là một byte tiếp tục.
  • Nếu không, đó là byte đầu tiên của chuỗi nhiều byte và số lượng hàng đầu 1 bit cho biết tổng số byte có trong tổng số này (110... nghĩa là hai byte, 1110... nghĩa là ba byte, v.v.).
+1

giải thích tuyệt vời. đã giúp rất nhiều. cảm ơn. –

Các vấn đề liên quan