Salad UN

To Taste The Salad Of Life.

« 用ASP上传Excel 表格并导入到数据库Asp遍列复制文件夹图片,并添加到数据库程序代码 »

把UTF-8转换成gb2312 编码的一些方法

[ At 2008-6-6 By Ash   0 comments ]

近来遇到一麻烦的问题,就是将utf的数据要提交到外站,比如说支付宝,网银,顺便鄙视下网银的技术服务,一开始还说加个encoding=utf-8就能解决问题,感觉他们好像有数据处理接口一样,结果不行,耽误我时间,然后还满会推卸责任的,发个搜索出来.net的转换程序给我看,要搜索我自己不会么?

反正总得对客户负责,我就只有自己动手找啦。

网上找了找,全部先放着,方便以后来找。

第一个

<%
'个人代码风格注释(变量名中第一个小写字母表表示变量类型)
'i:为Integer型;
's:为String;
Function U2UTF8(Byval a_iNum)
     Dim sResult,sUTF8
     Dim iTemp,iHexNum,i

     iHexNum = Trim(a_iNum)

     If iHexNum = "" Then
         Exit Function
     End If

     sResult = ""

     If (iHexNum < 128) Then
         sResult = sResult & iHexNum
     ElseIf (iHexNum < 2048) Then
         sResult = ChrB(&H80 + (iHexNum And &H3F))
         iHexNum = iHexNum \ &H40
         sResult = ChrB(&HC0 + (iHexNum And &H1F)) & sResult
     ElseIf (iHexNum < 65536) Then
         sResult = ChrB(&H80 + (iHexNum And &H3F))
         iHexNum = iHexNum \ &H40
         sResult = ChrB(&H80 + (iHexNum And &H3F)) & sResult
         iHexNum = iHexNum \ &H40
         sResult = ChrB(&HE0 + (iHexNum And &HF)) & sResult
     End If

     U2UTF8 = sResult
End Function

Function GB2UTF(Byval a_sStr)
     Dim sGB,sResult,sTemp
     Dim iLen,iUnicode,iTemp,i

     sGB = Trim(a_sStr)
     iLen = Len(sGB)
     For i = 1 To iLen
          sTemp = Mid(sGB,i,1)
          iTemp = Asc(sTemp)

          If (iTemp>127 OR iTemp<0) Then
              iUnicode = AscW(sTemp)
              If iUnicode<0 Then
                  iUnicode = iUnicode + 65536
              End If
         Else
             iUnicode = iTemp
         End If

         sResult = sResult & U2UTF8(iUnicode)
     Next

     GB2UTF = sResult
End Function

'调用方法
Response.BinaryWrite(GB2UTF("中国人"))

%>

 

第二个

ASP/Visual Basic代码
  1. <%    
  2. '用途:將UTF-8編碼漢字轉換為GB2312碼,兼容英文和數字    
  3. '用法:Response.write UTF2GB("%E9%83%BD%E5%B8%82%E6%83%85%E7%B7%A3 %E6%98%9F%E5%BA%A7")    
  4.   
  5. function UTF2GB(UTFStr)    
  6. for Dig=1 to len(UTFStr)    
  7. if mid(UTFStr,Dig,1)="%" then    
  8. if len(UTFStr) >= Dig+8 then    
  9. GBStr=GBStr & ConvChinese(mid(UTFStr,Dig,9))    
  10. Dig=Dig+8    
  11. else    
  12. GBStr=GBStr & mid(UTFStr,Dig,1)    
  13. end if    
  14. else    
  15. GBStr=GBStr & mid(UTFStr,Dig,1)    
  16. end if    
  17. next    
  18. UTF2GB=GBStr    
  19. end function    
  20.   
  21. function ConvChinese(x)    
  22. A=split(mid(x,2),"%")    
  23. i=0    
  24. j=0    
  25.   
  26. for i=0 to ubound(A)    
  27. A(i)=c16to2(A(i))    
  28. next    
  29.   
  30. for i=0 to ubound(A)-1    
  31. DigS=instr(A(i),"0")    
  32. Unicode=""    
  33. for j=1 to DigS-1    
  34. if j=1 then    
  35. A(i)=right(A(i),len(A(i))-DigS)    
  36. Unicode=Unicode & A(i)    
  37. else    
  38. i=i+1    
  39. A(i)=right(A(i),len(A(i))-2)    
  40. Unicode=Unicode & A(i)    
  41. end if    
  42. next    
  43.   
  44. if len(c2to16(Unicode))=4 then    
  45. ConvChinese=ConvChinese & chrw(int("&H" & c2to16(Unicode)))    
  46. else    
  47. ConvChinese=ConvChinese & chr(int("&H" & c2to16(Unicode)))    
  48. end if    
  49. next    
  50. end function    
  51.   
  52. function c2to16(x)    
  53. i=1    
  54. for i=1 to len(x) step 4    
  55. c2to16=c2to16 & hex(c2to10(mid(x,i,4)))    
  56. next    
  57. end function    
  58.   
  59. function c2to10(x)    
  60. c2to10=0    
  61. if x="0" then exit function    
  62. i=0    
  63. for i= 0 to len(x) -1    
  64. if mid(x,len(x)-i,1)="1" then c2to10=c2to10+2^(i)    
  65. next    
  66. end function    
  67.   
  68. function c16to2(x)    
  69. i=0    
  70. for i=1 to len(trim(x))    
  71. tempstr= c10to2(cint(int("&h" & mid(x,i,1))))    
  72. do while len(tempstr)<4    
  73. tempstr="0" & tempstr    
  74. loop    
  75. c16to2=c16to2 & tempstr    
  76. next    
  77. end function    
  78.   
  79. function c10to2(x)    
  80. mysign=sgn(x)    
  81. x=abs(x)    
  82. DigS=1    
  83. do    
  84. if x<2^DigS then    
  85. exit do    
  86. else    
  87. DigS=DigS+1    
  88. end if    
  89. loop    
  90. tempnum=x    
  91.   
  92. i=0    
  93. for i=DigS to 1 step-1    
  94. if tempnum>=2^(i-1) then    
  95. tempnum=tempnum-2^(i-1)    
  96. c10to2=c10to2 & "1"    
  97. else    
  98. c10to2=c10to2 & "0"    
  99. end if    
  100. next    
  101. if mysign=-1 then c10to2="-" & c10to2    
  102. end function    
  103. %>  

第三个看看下面的文字,就知道了,在后来我加了这个,程序顶端
<%Session.CodePage=65001%>

<%@ codepage=936%>简体中文
<%@ codepage=950%>繁体中文
<%@ codepage=65001%>UTF-8

codepage指定了IIS按什么编码读取传递过来的串串(表单提交,地址栏传递等)。
出乱码的原因也就是网站要整合的时候模块编码不一样引起的。
不要转换任何模块网页的编码该utf-8的还是utf-8,该Gb22312的还是Gb2312
于是我将GB2312模块的conn.asp文件中加入了以下这段代码
<%@LANGUAGE="VBSCRIPT" CODEPAGE="936"%>
<%Session.CodePage=936%>
一切OK!
同样在在Utf-8模块的包文件(如conn.asp,但是要注意conn.asp必须是在第一行调用)最前面加上
<%@LANGUAGE="VBSCRIPT" CODEPAGE="65001"%>
<%Session.CodePage=65001%>

 

第四个

用XMLHTTP Post Form时的表单乱码有两方面的原因——Post表单数据时中文乱码;服务器Response被XMLHTTP不正确编码引起的乱码。换句话说,本文主要解决两个问题——怎样正确Post中文内容&怎样正确显示得到的中文内容。

Part I Post中文内容

先看看E文的表单是怎么提交的:

<SCRIPT language="JavaScript">
strA = "submit1=Submit&text1=scsdfsd";
var oReq = new ActiveXObject("MSXML2.XMLHTTP");
oReq.open("POST","http://ServerName/VDir/TstResult.asp",false);
oReq.setRequestHeader("Content-Length",strA.length);  
oReq.setRequestHeader("CONTENT-TYPE","application/x-www-form-urlencoded");
oReq.send(strA);
</ScRIPT>

如果把strA = "submit1=Submit&text1=scsdfsd";换成:
strA = "submit1=Submit&text1=中文";

你会发现提交上去的东东根本不对,ASP中Request.Form("Text1")根本取不到值。俺用Request.BinaryRead把一个HTML Form中的Post内容写出来看了看,才发现问题——Form提交时也要编码的,编码后的中文是类似于%??%??的转义字符,比如“中文”就被编码为:%D6%D0%CE%C4。呵呵,也怪俺笨,人家CONTENT-TYPE里明明写的清清楚楚——application/x-www-form-urlencoded,urlencoded嘛当然就是这个样子了。既然这样,那我们也知道该怎么办了——自己做转换,代码见下:

<SCRIPT language="VBScript">
Function URLEncoding(vstrIn)
     strReturn = ""
     For i = 1 To Len(vstrIn)
         ThisChr = Mid(vStrIn,i,1)
         If Abs(Asc(ThisChr)) < &HFF Then
             strReturn = strReturn & ThisChr
         Else
             innerCode = Asc(ThisChr)
             If innerCode < 0 Then
                 innerCode = innerCode + &H10000
             End If
             Hight8 = (innerCode   And &HFF00)\ &HFF
             Low8 = innerCode And &HFF
             strReturn = strReturn & "%" & Hex(Hight8) &   "%" & Hex(Low8)
         End If
     Next
     URLEncoding = strReturn
End Function

strA = URLEncoding("submit1=Submit&text1=中文")
oReq = CreateObject("MSXML2.XMLHTTP")
oReq.open "POST","http://ServerName/VDir/TstResult.asp",false
oReq.setRequestHeader "Content-Length",Len(strA)
oReq.setRequestHeader "CONTENT-TYPE","application/x-www-form-urlencoded"
oReq.send strA
</ScRIPT>

(在这里俺把前面的JavaScript的代码改成了VBScript,不是吃饱了撑的没事干,原因见后)

Part II.正确显示得到的中文内容

OK,如果你在Server端把Form的内容写到数据库/文件的话,你在那里看到的中文毫无问题,但是,假如你想看看Server的Response——问题来了:如果Response的结果不是XML,XMLHTTP.responseXML里当然是不会有东东的,那就用responseText好了,在代码的最后加一句:

alert(oReq.responseText)
看看俺们辛勤劳动的结果   :P

但是但是.....怎么所有的中文全变成了方格? (我打不出来,有兴趣自己去试,也不用Post,Get一个含有中文的网页就可以发现了。)

原因很简单:XMLHTTP得到Response时假定Response是UTF8编码的,如果Response是XML,那还可以通过encoding来指定编码,但HTML就不行了。(见鬼的GB2312,再次打倒!)所以它把含GB2312编码的HTML当成UTF8格式,不出错才有鬼!

不过好在还有补救的办法:XMLHTTP的responseBody 属性里包含的可是未解码的Resonse——"a raw undecoded bytes as received directly from the server" :),唯一的问题是,responseBody返回的是一个unsigned bytes数组,我们怎么去访问它,怎么把它转换成BSTR?

这就是为什么我在上面把代码改成VBScript的原因——VBScript Can do it,but JavaScript Cannot!

代码见下:
<SCRIPT language="VBScript">
Function URLEncoding(vstrIn)
     strReturn = ""
     For i = 1 To Len(vstrIn)
         ThisChr = Mid(vStrIn,i,1)
         If Abs(Asc(ThisChr)) < &HFF Then
             strReturn = strReturn & ThisChr
         Else
             innerCode = Asc(ThisChr)
             If innerCode < 0 Then
                 innerCode = innerCode + &H10000
             End If
             Hight8 = (innerCode   And &HFF00)\ &HFF
             Low8 = innerCode And &HFF
             strReturn = strReturn & "%" & Hex(Hight8) &   "%" & Hex(Low8)
         End If
     Next
     URLEncoding = strReturn
End Function

Function bytes2BSTR(vIn)
     strReturn = ""
     For i = 1 To LenB(vIn)
         ThisCharCode = AscB(MidB(vIn,i,1))
         If ThisCharCode < &H80 Then
             strReturn = strReturn & Chr(ThisCharCode)
         Else
             NextCharCode = AscB(MidB(vIn,i+1,1))
             strReturn = strReturn & Chr(CLng(ThisCharCode) * &H100 + CInt(NextCharCode))
             i = i + 1
         End If
     Next
     bytes2BSTR = strReturn
End Function

strA = URLEncoding("submit1=Submit&text1=中文")
oReq = CreateObject("MSXML2.XMLHTTP")
oReq.open "POST","http://ServerName/VDir/TstResult.asp",false
oReq.setRequestHeader "Content-Length",Len(strA)
oReq.setRequestHeader "CONTENT-TYPE","application/x-www-form-urlencoded"
oReq.send strA
alert bytes2BSTR(oReq.responseBody)
</ScRIPT>

 

 

 

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

日历

最新评论及回复

最近发表

Powered By Z-Blog 1.8 Spirit Build 80722 Code detection by Codefense

Copyright 2008 www.s-un.cn. Some Rights Reserved.