找回密码
 立即注册→加入我们

QQ登录

只需一步,快速开始

搜索
热搜: 下载 VB C 实现 编写
查看: 4158|回复: 5

【VB6】不借助API将UTF-8编码的字符串解码为VB6能识别的字符串

[复制链接]
发表于 2017-11-23 10:50:47 | 显示全部楼层 |阅读模式

欢迎访问技术宅的结界,请注册或者登录吧。

您需要 登录 才可以下载或查看,没有账号?立即注册→加入我们

×
  1. Private Function utf8toString(utf8byte() As Byte) As String
  2. Dim I&
  3. Dim charcode As Long
  4. Dim cb As Long
  5. cb = UBound(utf8byte) + 1

  6. Do While I < cb
  7.     If (utf8byte(I) And &HFE) = &HFC& Then '1111110x
  8.         If I + 6 <= cb Then
  9.             charcode = _
  10.                 ((utf8byte(I + 0) And &H1&) * &H40000000) Or _
  11.                 ((utf8byte(I + 1) And &H3F&) * &H1000000) Or _
  12.                 ((utf8byte(I + 2) And &H3F&) * &H40000) Or _
  13.                 ((utf8byte(I + 3) And &H3F&) * &H1000&) Or _
  14.                 ((utf8byte(I + 4) And &H3F&) * &H40&) Or _
  15.                 ((utf8byte(I + 5) And &H3F&))
  16.             I = I + 6
  17.         Else
  18.             Exit Do
  19.         End If
  20.     ElseIf (utf8byte(I) And &HFC) = &HF8& Then '111110xx
  21.         If I + 5 <= cb Then
  22.             charcode = _
  23.                 ((utf8byte(I + 0) And &H3&) * &H1000000) Or _
  24.                 ((utf8byte(I + 1) And &H3F&) * &H40000) Or _
  25.                 ((utf8byte(I + 2) And &H3F&) * &H1000&) Or _
  26.                 ((utf8byte(I + 3) And &H3F&) * &H40&) Or _
  27.                 ((utf8byte(I + 4) And &H3F&))
  28.             I = I + 5
  29.         Else
  30.             Exit Do
  31.         End If
  32.     ElseIf (utf8byte(I) And &HF8) = &HF0& Then '11110xxx
  33.         If I + 4 <= cb Then
  34.             charcode = _
  35.                 ((utf8byte(I + 0) And &H7&) * &H40000) Or _
  36.                 ((utf8byte(I + 1) And &H3F&) * &H1000&) Or _
  37.                 ((utf8byte(I + 2) And &H3F&) * &H40&) Or _
  38.                 ((utf8byte(I + 3) And &H3F&))
  39.             I = I + 4
  40.         Else
  41.             Exit Do
  42.         End If
  43.     ElseIf (utf8byte(I) And &HF0) = &HE0& Then '1110xxxx
  44.         If I + 3 <= cb Then
  45.             charcode = _
  46.                 ((utf8byte(I + 0) And &HF&) * &H1000&) Or _
  47.                 ((utf8byte(I + 1) And &H3F&) * &H40&) Or _
  48.                 ((utf8byte(I + 2) And &H3F&))
  49.             I = I + 3
  50.         Else
  51.             Exit Do
  52.         End If
  53.     ElseIf (utf8byte(I) And &HE0) = &HC0& Then '110xxxxx
  54.         If I + 2 <= cb Then
  55.             charcode = _
  56.                 ((utf8byte(I + 0) And &H1F&) * &H40&) Or _
  57.                 ((utf8byte(I + 1) And &H3F&))
  58.             I = I + 2
  59.         Else
  60.             Exit Do
  61.         End If
  62.     ElseIf (utf8byte(I) And &HC0) = &H80& Then '10xxxxxx
  63.         '遇到高2位是10的字符,这是不应该出现的。
  64.         Exit Do
  65.     ElseIf (utf8byte(I) And &H80) = &H0& Then  '&Hxxxxxx
  66.         charcode = utf8byte(I) And &H7F
  67.         I = I + 1
  68.     Else
  69.         Exit Do
  70.     End If
  71.     utf8toString = utf8toString & ChrW(charcode)
  72. Loop
  73. End Function
复制代码

本帖被以下淘专辑推荐:

回复

使用道具 举报

发表于 2024-6-9 22:03:50 | 显示全部楼层
手头没有VB6 用VFB写的 也没法调试 逻辑纯靠脑补...

Function VB6_UTF8_TO_STRING(UTF8() As Byte, Optional ByVal nByte As Long = -1) As String
    If UBound(UTF8) = -1 Or nByte = 0 Then Exit Function
    Dim Buf() As Byte, k As Long   ''输出缓存,缓存字节计数器
    Dim i As Long, j As Long       ''状态量(j=0初始态; j=[1-5]UTF8后续字节数)
    Dim c As Long    ''UNICODE缓冲
    ReDim Buf(0 To UBound(UTF8) - LBound(UTF8) + 1)
    For i = LBound(UTF8) To UBound(UTF8)
        Select Case UTF8(i)
            Case &H1 To &H7F      ''ANSI
                If j <> 0 Then Exit For
                Buf(k) = UTF8(i) : k = k + 1
            Case &H80 To &HBF     ''UTF8的后续字节: 10xxxxxx
                j = j - 1 : If j < 0 Then Exit For
                ''UNICODE左移6位 + UTF8低6位
                c = (c * &H40& ) Or (UTF8(i) And &H3F)
                If j = 0 Then
                    Buf(k) = (c And &HFF&) : k = k + 1
                    Buf(k) = ((c And &HFF00&) \ &H100&) : k = k + 1
                    If c > &H10000 Then        ''多字节可能会出现UTF32
                        Buf(k) = ((c And &HFF0000) \ &H10000&) : k = k + 1
                        Buf(k) = ((c And &HFF000000) \ &H1000000&) : k = k + 1
                    End If : c = 0
                End If
            Case &HC0 To &HFD     ''UTF8的首字节
                If j <> 0 Then Exit For
                Select Case UTF8(i)
                    Case &HD0 To &HDF          ''3字节: 1110xxxx
                        j = 2 : c = (UTF8(i) And &H0F)
                    Case &HF0 To &HF7          ''4字节: 11110xxx
                        j = 3 : c = (UTF8(i) And &H07)
                    Case &HC0 To &HCF          ''2字节: 110xxxxx
                        j = 1 : c = (UTF8(i) And &H1F)
                    Case &HF8 To &HFB          ''5字节: 111110xx
                        j = 4 : c = (UTF8(i) And &H03)
                    Case &HFC To &HFD          ''6字节: 1111110x
                        j = 5 : c = (UTF8(i) And &H01)
                End Select
            Case 0                ''终止符\0
                If nByte > 0 Then j = -1       ''数据中出现了0,设置为错误状态
                Exit For                       ''否则认为读完了全部数据,总之必须退出
            Case Else             ''其它非法字符
                j = -1 : Exit For
        End Select
        nByte = nByte - 1 : If nByte = 0 Then Exit For
    Next
    ''If j <> 0 Then
    ''  Debug.Print "转换过程中检测到非法的字符数据"
    ''  Exit Function
    ''End If
    If k > 0 Then   ''最大限度输出转换的结果
        ReDim Preserve Buf(0 To k - 1)
        VB6_UTF8_TO_STRING = Buf   ''这要StrConv吗?
    End If          ''最后1个字符可能乱码(解决的办法是再增加一个字符数计数器)
End Function
回复 赞! 1 靠! 0

使用道具 举报

发表于 2017-11-23 16:10:11 | 显示全部楼层
  拜模已经不足以对你的表达了
回复 赞! 靠!

使用道具 举报

发表于 2022-5-9 15:56:52 | 显示全部楼层

楼主大能,感谢感谢
回复 赞! 靠!

使用道具 举报

发表于 2023-9-26 18:30:54 | 显示全部楼层
谢谢A5的分享,HAHA...
回复 赞! 靠!

使用道具 举报

发表于 2023-10-9 18:16:56 | 显示全部楼层
本帖最后由 tlwh163 于 2023-10-9 18:17 编辑

''1.    不会出现的字节:       0xC0, 0xC1, 0xF5-0xFF
''2.    字符的第1个字节值域:  0-0x7F(ANSI), 0xC2-0xF4(UTF8)
''3.    字符的第2+个字节值域:  0x80-0xBF
回复 赞! 靠!

使用道具 举报

本版积分规则

QQ|Archiver|小黑屋|技术宅的结界 ( 滇ICP备16008837号 )|网站地图

GMT+8, 2024-11-23 17:38 , Processed in 0.040598 second(s), 29 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表