`

多端点传输杜绝乱码方案

阅读更多

多个端点之前传输字符串(String),实际上是传输字节流(Byte[])。如果发送方采用UTF8编码将字符串变为字节流(Byte[]=String.getBytes("UTF8")),当接收方接受到后,却使用GBK来解码字节流到字符串(String = new String(byte[],"GBK");),那么就会出现乱码。为了避免乱码这种情况,通讯双方需要知道对方的编码格式,或者双方统一编码。

 

本文介绍的方式,是无需定编码的方式,来杜绝乱码,原理就是使用UNICODE这个字符集和UTF16编码格式。本方案的驱动来源于实际工作中遇到3个端点之间的通讯需要相互约定编码格式,导致部署时麻烦而且容易乱码。

 

1 对于JAVA发送端,

发送字符串前,先转为UNICODE文本,具体处理如下:

 

    public static String toUnicodeString(String s){
    	StringBuilder strb = new StringBuilder();
    	char[] c = s.toCharArray();
    	for(int i=0,len=c.length;i<len;i++){
	    	if(c[i] < 128){
	    		strb.append(c[i]);
	    	}else{
	    		strb.append("\\u");
	    		String hex = Integer.toHexString(c[i]);
	    		
	    		if(hex.length()<4){
	    			int padLen = 4-hex.length();//需要左补齐的0
	    			for(int k=0;k<padLen;k++){
	    				hex = "0" + hex;
	    			}
	    		}
	    		strb.append(hex);
	    	}
    	}
    	return strb.toString();
    }

上述代码的原理在于,利用JAVA内存中使用UTF16编码保存字符串的特点,将字符串转换为UNICODE文本。

 

这样子,例如

”中文abc"

 通过如下调用

 

String unicodeStr = toUnicodeString("中文abc");
System.out.println(unicodeStr);

 

变成了

\u4e2d\u6587abc

 注意这个最后的字符串,它仅仅包含0-127编码的基本字符,这些字符在所有的编码格式中,解析和被解析都是一致的,不会存在乱码问题。

 

2 对于JAVA接受端,

在使用接受的UNICODE文本字符串之前,先转换为正确的字符串。

 

    /**
     * 将字符的unicode部分,全部转换成具体字符
     * @param s
     * @return
     */
    public static String parseUnicodeString(String s){
    	StringBuilder rtn = new StringBuilder();
    	for(int i=0,len=s.length();i<len;i++){
    		char c = s.charAt(i);
    		if(c=='\\'){
    			i++;
    			char c1 = s.charAt(i);
    			if(c1 == 'u'){
    				try{
    					char c_chinese = (char) Integer.parseInt(s.substring(i+1,i+1+4),16);
    					rtn.append(c_chinese);
    					i += 4;
    				}catch(Exception e){
    					throw new RuntimeException("parseUnicodeString出错",e);
    				}
    			}else{
    				rtn.append(c).append(c1);
    			}
    		}else{
    			rtn.append(c);
    		}
    	}
    	return rtn.toString();
    }

 这样子,例如

 

\u4e2d\u6587abc

 通过如下调用

 

		String s = parseUnicodeString("\u4e2d\u6587abc");
		System.out.println(s);

 

变成了

”中文abc"

 

3 对于C++发送端

 

std::string Util::toUnicodeString(std::string& strascii)  
{   string rtn = "";
    int widesize = MultiByteToWideChar (CP_ACP, 0, (char*)strascii.c_str(), -1, NULL, 0);  
    wchar_t * wcharBuf = new wchar_t[widesize];
    int convresult = MultiByteToWideChar (CP_ACP, 0, (char*)strascii.c_str(), -1, wcharBuf, widesize);
	
	for(int i=0;i<widesize-1;i++){
		if(wcharBuf[i]<128){
			rtn += (char)wcharBuf[i];
		}else{
			char hex[6]={0};
			sprintf(hex,"\\u%04x",wcharBuf[i]);
			rtn += hex;
		}
	}
	
	delete [] wcharBuf;
    return rtn;  
} 

关键在于WIDECHAR,由于JAVA本身在内存的字符串就是用WIDECHAR存放,所以节省了一些步骤,但是C++就没有这个特性,所以需要MultiByteToWideChar来将ANSI转换为UTF16格式,最后存放在WIDECHAR。

 

 

 4 对于C++接收端

 

std::string Util::parseUnicodeString(std::string& strUnicodeFormat)  
{  
	string rtn = "";
	wstring wstr;
	wstr.reserve(strUnicodeFormat.length()*2);
	//将ascii char转换为unicode wchar
	for(int i=0;i<strUnicodeFormat.length();i++){
		char c = strUnicodeFormat[i];
		if('\\' == c){
			i++;
			char c1 = strUnicodeFormat[i];
			if('u'==c1){
				string hex = strUnicodeFormat.substr(i+1,4);
				WCHAR wcs[2];
				memset(wcs,0,sizeof(wcs));
				wcs[0] = (WCHAR)(strtol(hex.c_str(),NULL,16));
				wstr.append(wcs);
				i += 4;
			}else{
				WCHAR wcs[2];
				memset(wcs,0,sizeof(wcs));
				wcs[0] = (WCHAR)c;
				
				WCHAR wcs1[2];
				memset(wcs1,0,sizeof(wcs));
				wcs1[0] = (WCHAR)c1;
				
				wstr.append(wcs).append(wcs1);
			}
		}else{
			WCHAR wcs[2];
			memset(wcs,0,sizeof(wcs));
			wcs[0] = (WCHAR)c;
			wstr.append(wcs);
		}
	}
	return UnicodeToANSI(wstr);
} 

 5 优点与缺点

这种方案的好处就是无需担心文本的乱码问题了,利用了UNICODE,简单可靠。

缺点在于

1. 字符串发送和接受,需要一定程度上的额外处理。

2. 传送的字节流也会有一定程度上的增大。这个可以用GZIP去规避。(C++使用zlib,Java使用GzipOutputStream)。

 

没有完美的方案,好方案是权衡轻重后得出的方案。对于本人来说,该方案带来的效率下降并不大,对比起乱码这种严重又纠结的问题(如果端点很多,程序编码的配置就很要命了),带来的得益要多得多;对于部署人员来说,则减少了部署的工作量和压力,皆大欢喜:)

 

 

1
1
分享到:
评论
3 楼 liushilang 2013-07-08  
好东西,也是一种好的思想
2 楼 lazy_ 2013-07-06  
qlstrike 写道
是个好想法,不知道有没有实际线上练过啊

这是正式生产环境中运行的代码,仅仅有少量的修改
1 楼 qlstrike 2013-07-05  
是个好想法,不知道有没有实际线上练过啊

相关推荐

    端点准入防御解决方案.pdf

    端点准入防御解决方案.pdf端点准入防御解决方案.pdf端点准入防御解决方案.pdf端点准入防御解决方案.pdf端点准入防御解决方案.pdf端点准入防御解决方案.pdf端点准入防御解决方案.pdf端点准入防御解决方案.pdf

    EAD端点主动防御解决方案

    H3C端点准入防御(EAD,Endpoint Admission Defense)解决方案则从用户终端准入控制入手,整合网络接入控制与终端安全产品,通过安全客户端、安全策略服务器、网络设备以及第三方软件的联动,对接入网络的用户终端...

    EAD端点准入防御解决方案介绍.pdf

    EAD端点准入防御解决方案介绍.pdfEAD端点准入防御解决方案介绍.pdfEAD端点准入防御解决方案介绍.pdfEAD端点准入防御解决方案介绍.pdfEAD端点准入防御解决方案介绍.pdfEAD端点准入防御解决方案介绍.pdfEAD端点准入...

    端点准入防御解决方案复习过程.docx

    端点准入防御解决方案复习过程.docx端点准入防御解决方案复习过程.docx端点准入防御解决方案复习过程.docx端点准入防御解决方案复习过程.docx端点准入防御解决方案复习过程.docx端点准入防御解决方案复习过程.docx...

    端点准入防御解决方案复习过程.pdf

    端点准入防御解决方案复习过程.pdf端点准入防御解决方案复习过程.pdf端点准入防御解决方案复习过程.pdf端点准入防御解决方案复习过程.pdf端点准入防御解决方案复习过程.pdf端点准入防御解决方案复习过程.pdf端点准入...

    JAVA多线程端点续传下载

    JAVA多线程端点续传下载JAVA多线程端点续传下载JAVA多线程端点续传下载JAVA多线程端点续传下载JAVA多线程端点续传下载JAVA多线程端点续传下载JAVA多线程端点续传下载JAVA多线程端点续传下载JAVA多线程端点续传下载...

    usb2.0端点控制传输

    端点0控制传输详解

    Check Point把间谍软件防御功能整合至其端点安全解决方案

    在互联网安全领域处于全球领先地位的Check Point软件技术有限公司宣布推出一款先进的间谍软件防御方案,它整合了Check Point领先行业的端点安全解决方案。这款整合的产品为客户提供最全面的端点安全,包括在单一客户...

    端点准入防御解决方案

    EAD提供了一个全新的安全防御体系,该系统作为网络安全管理的平台,将防病毒功能、自动升级系统补丁等第三方软件提供的网络安全功能、网络设备接入控制功能、用户接入行为管理功能相融合,加强了对用户终端的集中...

    华为3com-EAD端点准入防御解决方案

    在现有企业网中,只需对网络设备和第三方软件进行简单升级,即可实现接入控制和防病毒的联动,达到端点准入控制的目的,有效保护用户的网络投资。EAD也是一个开放的安全解决方案。EAD系统中,安全策略服务器与网络...

    基于情报的端点安全防护方案介绍.pptx

    介绍MacAfee动态端点威胁防护战略,新一代端点威胁防御解决方案

    EAD端点主动防御解决方案在用友软件成功应用

    用友集团以软件为核心产品,因而研发部门对于网络信息安全有着严格...针对用友集团对于终端的安全需求,H3C公司采用EAD端点主动防御解决方案,实现了用户身份管理及安全控制策略、终端安全管理、 用户权限控制等需求。

    H3CEAD端点准入防御组件解决方案.pdf

    H3CEAD端点准入防御组件解决方案.pdfH3CEAD端点准入防御组件解决方案.pdfH3CEAD端点准入防御组件解决方案.pdfH3CEAD端点准入防御组件解决方案.pdfH3CEAD端点准入防御组件解决方案.pdfH3CEAD端点准入防御组件解决方案...

    H3CEAD端点准入防御组件解决方案.docx

    H3CEAD端点准入防御组件解决方案.docxH3CEAD端点准入防御组件解决方案.docxH3CEAD端点准入防御组件解决方案.docxH3CEAD端点准入防御组件解决方案.docxH3CEAD端点准入防御组件解决方案.docxH3CEAD端点准入防御组件...

    多个字的端点检测

    语音多字的端点检测,找出清浊分界,并以线的形式标出界线

    Symantec 端点安全SEP解决方案

    Symantec™ Endpoint Protection 将 Symantec AntiVirus™ 与高级威胁防御功能相结合,可以为笔记本、台式机和 服务器提供无与伦比的恶意软件防护能力。它甚至可以 防御那些最复杂的攻击,这些攻击能够躲避传统的...

    Windows统一端点管理方案.pdf

    Windows统一端点管理方案.pdf

    EAD端点准入防御解决策划方案介绍.doc

    EAD端点准入防御解决策划方案介绍.doc

    H3CEAD端点准入防御组件解决方案.doc

    H3CEAD端点准入防御组件解决方案.doc

    语音识别端点检测语音识别端点检测

    语音识别端点检测语音识别端点检测语音识别端点检测语音识别端点检测语音识别端点检测语音识别端点检测

Global site tag (gtag.js) - Google Analytics