Đó 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ạ 0xc0
là 11 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.).
giải thích tuyệt vời. đã giúp rất nhiều. cảm ơn. –