国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
VB.net 中文處理問題 (Unicode 和 Ascii的編碼問題)

        前段時間電腦顯示中文不正常,就是因為把“控制面板”里的“語言地區(qū)設(shè)置”  高級選項 中設(shè)置為把非Unicode字符當English Unite State 地區(qū)來處理,不是China (PRC). 因為要做測試的程序不支持中文,改了上面說到的語言選項之后就出問題了。結(jié)果別人發(fā)來的QQ信息都看不到,全部顯示亂碼。
        跟蹤調(diào)試了好幾次,終于把這個問題解決了。首先修改的是StringtoHex 和HexToString 兩個函數(shù),可以看出這兩個函數(shù)明顯不支持中文。它在里面使用Len()Asc() Hex()等函數(shù)來作String變量到二進制字符串的轉(zhuǎn)換。由于中文漢字有兩個字節(jié)大小,而Len()都是但作一個長度來處理,在加上Asc()處理中文字符,都是返回負數(shù)。所以重寫了這兩個函數(shù)改成對字符串字節(jié)作處理,直接處理Byte到二進制表示法字符串的變換,很方便。

使用

 dim strtemp as string
 dim a() as byte
 a=System.Text.Encoding.Unicode.GetBytes(strTemp.tochar)
便可以獲取字符串保存的數(shù)據(jù)byte信息了。

    但是關(guān)鍵的地方 還不是上面的那個函數(shù),而是  一個加解密的函數(shù)。經(jīng)過跟蹤發(fā)現(xiàn),這個函數(shù)加密后返回的字符串字節(jié)長度增加了??梢钥吹绞窍扔胠en()來計算字符串長度,再調(diào)用微軟的加密解密函數(shù)庫來加密,然后用一個 Left()函數(shù)來截取加密后的字符串返回。就是控制面板里的語言選項設(shè)置導(dǎo)致把加密函數(shù)庫返回的字符串字節(jié)當作Unicode來處理,所以最后采用Left()截取的字符串和傳進去的字符串字節(jié)長度不一樣,這就是問題的根源。 由于VB.NET中全部字符串都是當作Unicode來處理。當把Ascii字母傳給微軟加密庫之后,得到的卻是VB.net自動轉(zhuǎn)換而來的Unicode字符。我曾想過字節(jié)編寫函數(shù)把這個unicode 的兩個字節(jié)分離成兩個AscIi字符。但實現(xiàn)起來并不十分成功,并不如想象中的簡單。網(wǎng)上找到如下資料:


////////////////////////////////////////////////////////////
Q  如何實現(xiàn)ANSI和UNICODE的相互轉(zhuǎn)換 

將ANSI轉(zhuǎn)換到Unicode 
(1)通過L這個宏來實現(xiàn),例如:  CLSIDFromProgID(  L"MAPI.Folder",&clsid); 
(2)通過MultiByteToWideChar函數(shù)實現(xiàn)轉(zhuǎn)換,例如: 
char  *szProgID  =  "MAPI.Folder"; 
WCHAR  szWideProgID[128]; 
CLSID  clsid; 
long  lLen  =  MultiByteToWideChar(CP_ACP,0,szProgID,strlen(szProgID),szWideProgID,sizeof(szWideProgID)); 
szWideProgID[lLen]  =  '\0';   
(3)通過A2W宏來實現(xiàn),例如:   
USES_CONVERSION;   
CLSIDFromProgID(  A2W(szProgID),&clsid);   
 
將Unicode轉(zhuǎn)換到ANSI 
(1)使用WideCharToMultiByte,例如: 
//  假設(shè)已經(jīng)有了一個Unicode  串  wszSomeString...   
char  szANSIString  [MAX_PATH];   
WideCharToMultiByte  (  CP_ACP,  WC_COMPOSITECHECK,  wszSomeString,  -1,  szANSIString,  sizeof(szANSIString),  NULL,  NULL  ); 


(2)使用W2A宏來實現(xiàn),例如: 
USES_CONVERSION; 
pTemp=W2A(wszSomeString);   
 
注意在轉(zhuǎn)換時可能存在的問題: 
因為ANSI轉(zhuǎn)UNICODE,如果使用A2W或MultiByteToWideChar(第一個參數(shù)是CP_ACP)的話,是根據(jù)系統(tǒng)默認的轉(zhuǎn)碼表,把轉(zhuǎn)入的ANSI字符串看作Multi-Bytes字符串處理的,如果是中文(中文windows默認就是中文),一個大于0x87的byte可能和下一 byte一起被看作一個漢字,然后根據(jù)漢字的Unicode編碼轉(zhuǎn)換為相同的Unicode漢字,如果找不到相應(yīng)的編碼,一般就用一個默認的字符來取代它(一般是問號"?"),由此看,如果隨便把一段數(shù)據(jù)給他轉(zhuǎn),轉(zhuǎn)化很復(fù)雜而且極可能不可逆,而且你加密過的ANSI碼是相當混亂的有很多〉0x87的 byte,轉(zhuǎn)換就變得不可逆了。 
建議自己直接就這樣寫: 
CHAR  lpANSI[COUNT]; 
WCHAR  lpUnicode[COUNT]; 
int  i  =  0;   
while(lpANSI[i]  !=  '\0'  )  { 
       lpUnicode[i]  =  (WCHAR)lpANSI[i]; 

lpUnicode[i]  =  L'\0'; 
然后按相同的方法轉(zhuǎn)回來,因為對于0~0x87的ANSI字符串,對應(yīng)的Unicode碼就是相同的16位值,至于其他的,你的字符串反正加了密,沒必要轉(zhuǎn)換成顯示出來是一樣的字符,就按同樣的方法處理了,其實如果中間的字符串不用顯示或別的,直接reutrn  (LPWSTR)lpANSI;過去也可以,  反正接受的時候自己清楚就可以了。 
/////////////////////////////////////////////////////////////////////////


        我記得再VB中也是有StrConV這個函數(shù)可以用的,結(jié)果發(fā)現(xiàn)現(xiàn)在VB.net中的這個函數(shù)和以前不同了,可能是因為VB.NET全部都是Unicode字符串。嘗試用Systme.Text.Encoding.Ascii ,Systme.Text.Encoding.Unicode.getstring (), 結(jié)果摸索了半天沒有進展。得出結(jié)論VB.NET中Unicode和Ascii字符的處理是很吃力。我指的是Unicode字節(jié)的分離。  看來只能取巧了。因為微軟的加解密函數(shù)庫中的函數(shù)庫是采用Byte來加解密的(這點可以由C語言聲明看出),所以VB中調(diào)用時把string型變量傳過去并不是十分合適,特別是這種Unicode和Ascii相關(guān)轉(zhuǎn)換很容易出問題。而直接把Byte傳給它更符合它的處理方法,也可以更好的控制byte的長度。前面說過字符串的字節(jié)信息是可以通過調(diào)用System.Text.Encoding.Unicode.GetBytes(strTemp.tochar) 來獲取的,所以加解密字符串也是很簡單的。解密之后的Byte數(shù)組,經(jīng)過 System.Text.Encoding.Unicode.GetString(strByteArray) 就可以取得了。這樣可以嚴格控制加解密的長度,不會出現(xiàn)Left()取得返回字符串長度不正確的問題。

修改微軟加解密API的聲明為如下形式:
 Private Declare Function CryptEncrypt Lib "advapi32.dll" (ByVal hSessionKey As Integer, ByVal hHash As Integer, ByVal Final As Integer,

ByVal dwFlags As Integer, ByRef pbData As Byte, ByRef pdwDataLen As Integer, ByVal dwBufLen As Integer) As Integer
 Private Declare Function CryptDecrypt Lib "advapi32.dll" (ByVal hSessionKey As Integer, ByVal hHash As Integer, ByVal Final As Integer,

ByVal dwFlags As Integer, ByRef pbData As Byte, ByRef pdwDataLen As Integer) As Integer

而原先  pbData 參數(shù) 是這樣聲明的 ByVal  pbData as String ,因為CryptEncrypt 函數(shù)本來就是對byte類型來作處理的,所以這

樣的改變沒有什么問題。相應(yīng)的調(diào)用改為:

  Dim strByteArray() As Byte = System.Text.Encoding.Unicode.GetBytes(Text.ToCharArray())
    
   …………………… 
     lngReturnValue = CryptEncrypt(hSessionKey, 0, 1, 0, strByteArray(0), lngLength, lngLength)
        
 


重新編譯運行,一切通過,問題解決!?。。。?!


總結(jié):注意加解密之后字符串的改變和編碼解碼問題。

本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
在VB 中調(diào)用動態(tài)連接庫
VB 字節(jié)數(shù)組和字符串的轉(zhuǎn)換問題 (String<>Byte)
在VB中使用API函數(shù)詳解
如何使用 Unicode 版和 Ansi 版 API – 中文
通過使用類型庫提高VB調(diào)用DLL函數(shù)的性能
SQLServer系統(tǒng)函數(shù)之字符串函數(shù)
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服