• VB---QP解码 - [简单]

    Tag:简单

    版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明
    http://cyinger-smiling.blogbus.com/logs/5672032.html

     Private Function QpDecode(inString As String) As String  '转载
      Dim myB     As Byte
      Dim myByte1     As Byte, myByte2       As Byte
      Dim convStr()     As Byte
      Dim mOutByte     As Byte
      Dim FinishPercent     As Long
      Dim TotalB, k       As Long
      Dim tmpByte     As Byte
       
      convStr = StrConv(inString, vbFromUnicode)
       
      TotalB = UBound(convStr)
      For k = 0 To TotalB
            myB = convStr(k)
            If myB = Asc("=") Then
                  k = k + 1
                  myByte1 = convStr(k)
                  If myByte1 = &HA Then
                              '如果是回车,继续
                  Else
                              '取第二个字节
                        k = k + 1
                        myByte2 = convStr(k)
                        Call DecodeByte(myByte1, myByte2, mOutByte)
                        If mOutByte >= 127 Then
                              If tmpByte <> 0 Then
                                    QpDecode = QpDecode & Chr(Val("&H" & Hex(tmpByte) & Hex(mOutByte)))
                                    tmpByte = 0
                              Else
                                    tmpByte = mOutByte
                              End If
                        Else
                              QpDecode = QpDecode & Chr(mOutByte)
                              tmpByte = 0
                        End If
                  End If
              Else
                      mOutByte = myB
                      QpDecode = QpDecode & Chr(mOutByte)
              End If
      Next
      End Function
      Private Sub DecodeByte(mInByte1 As Byte, mInByte2 As Byte, mOutByte As Byte)
      Dim tbyte1     As Integer, tbyte2       As Integer
      If mInByte1 > Asc("9") Then
              tbyte1 = mInByte1 - Asc("A") + 10
      Else
              tbyte1 = mInByte1 - Asc("0")
      End If
      If mInByte2 > Asc("9") Then
              tbyte2 = mInByte2 - Asc("A") + 10
      Else
              tbyte2 = mInByte2 - Asc("0")
      End If
      mOutByte = tbyte1 * 16 + tbyte2
      End Sub
       
      Private Sub EncodeByte(mInByte As Byte, mOutStr As String)
      If (mInByte >= 33 And mInByte <= 60) Or (mInByte >= 62 And mInByte <= 126) Then
              mOutStr = Chr(mInByte)
      Else
              If mInByte <= &HF Then
                      mOutStr = "=0" & Hex(mInByte)
              Else
                      mOutStr = "=" & Hex(mInByte)
              End If
      End If
    End Sub

         QP编码的规则是,对于信息中的7位字符不作重新编码,而是仅将8位的数据转成7位即可。我们可以看到,QP编码是字符对应的编码,每个未编码的二进制字符都会被编码成3个字符,即一个等号加上两个该字符的16进制值,如“=A8”,但这样的编码数为1:3,所以编码效率相对于其它编码方式而言相当低。但不可否认的是,这种编码方法非常简单,特别适合那些数据大多数是7位的ASCII码文本、偶尔插入8位字符的情况,但遗憾的是对汉字编码效果不够好,因为每个双字节汉字经过编码后会变成6个字节。具体规则如下:

        将一个字元用两个十六进制数表示,然后前面再加上一个「=」(等号)字元;除非这个字元符合下面其他的规则。比如原先 ASCII 的「=」(等号)字元,其十进制数值是 61,十六进制数值为 3D,所以经过 QP 编码后,变成了「=3D」。

        字元的数值(十进制数)介于 33 60、及 62 126 者不必经过编码。(61 是「等号」)

        字元 TAB SPACE 可以不经编码,但是不经编码的 TAB SPACE 不可以放在编码后每行字串的末尾;也就是說编码后的內容,一行字串中如果有 TAB SPACE 的話,其后面一定还有其它的字元。

    QP解码只是编码的逆过程,计算出每个等号后的两个十六进制字符所代表的数值进行解码,对于码值小于128的,单字节表示一个字符;大于128的,双字节表示一个字符。下面举例分析。例如:编码后的字符串为=C4=E3=BA=C3,解码后对应字符串为“你好”。3.3.3-2: QP解码示例

    十六进制值

    =C4=E3=BA=C3
    解码(十进制值)196227186195
    解码(二进制值)11000100 1110001110111010 11000011
    原字符

     

      以上两个函数分析如下:

      DecodeByte()函数是私有函数,对QP编码后的每组(以等号分割的每两个字节一组)信息进行QP解码,即计算这两个十六进制字符所代表的数值。当ASCII码小于“9”的ASCII码时,则减去“0”的ASCII码值(这是因为,当字符小于9时为了使编码位数一致,除在其前加“=”外还加了“0”);如果大于则减去“A”的ASCII码值再加10,即得到此位对应的十进制值,如“B”对应十进制值11。然后通过高字节*16+低字节得到解码数值。

      QpDecode()函数是私有函数,先用StrConv函数将QP编码后的字符串信息由Unicode转成系统的缺省码,然后将其分组(以等号分割,每两个字节一组)后调用DecodeByte()函数进行QP解码。第一个等号前及最后一个等号后三位起的字符不作QP解码(直接是ASCII编码)。对于DecodeByte()返回值小于128的(单字节字符)单字节表示一个字符,大于128(双字节字符)的两个字节表示一个字符。

     


    收藏到:Del.icio.us




    评论

  • 上面的解码是有问题的,对于一个扩展ASCII码,其值是大于127的,但它不是双字节,依然是一个字节,上面的解码函数不够全面!
  • 我怎么觉得有点怪啊这话
    Jolene回复说:
    昨天我改模板叫那小子帮忙,他非要回你留言不可。
    2007-06-11 01:36:45
  • 看到这些我知道这辈子我和计算机无缘了,一个头两个大……
    Jolene回复说:
    偶代表陈莹严重同意你这句话,恩,恩^^^
    2007-06-09 22:17:22