''扫描1段数据是否为UTF8编码,参数CharLength用于返回字符数
Public Function IS_UTF8(Utf8() As Byte, Optional ByRef CharLength As Long = 0) As Boolean
If (UBound(Utf8) - LBound(Utf8) + 1) = 0 Then
CharLength = 0: IS_UTF8 = False: Exit Function
End If
''0-15的前导1数量: 比如 15有4个前导1, 9有1个前导1, 7以下的数没有前导1
Dim PrecBit1(0 To 15) As Byte
PrecBit1(8) = 1: PrecBit1(9) = 1: PrecBit1(10) = 1: PrecBit1(11) = 1
PrecBit1(12) = 2: PrecBit1(13) = 2: PrecBit1(14) = 3: PrecBit1(15) = 4
Dim i As Long, mode As Long, nCount As Long
For i = LBound(Utf8) To UBound(Utf8)
Dim c As Byte: c = Utf8(i)
If c <= &H7F Then 'ANSI 0xxxxxxx
If mode = 0 Then nCount = nCount + 1 Else Exit For
ElseIf c <= &HBF Then 'UTF8后续字节 10xxxxxx
mode = mode - 1: If mode < 0 Then Exit For
If mode = 0 Then nCount = nCount + 1
Else 'UTF8首字节 110xxxxx - 1111110x
If mode <> 0 Then Exit For
Dim k As Byte: k = PrecBit1(c \ 16)
If k = 4 Then k = k + PrecBit1(c And 15)
mode = k - 1: If k > 6 Then Exit For ' FE FF 不可能出现
End If
Next
CharLength = nCount: IS_UTF8 = (mode = 0)
End Function