字符编码转换_进制转换(GB2312,GBK,JNI,HexTOStr)

//
/* 
ASCII 英文一个字节  
gb2312,gbk 中文两个字节,英文一个字节  
在中文系统中ansi一般指gb2312或gbk  
GB2312、GBK都属于双字节字符集 (DBCS)  
Utf-8 中文三个字节,英文一个字节  
Unicode 中文两个字节,英文两个字
*/
//
//
/*
GB2312 中国国家 标准码

	ANSI码(American National Standards Institute)
	美国国家  标准学会 的 标准码

	ASCII码(America Standard Code for Information Interchange)美国信息交换标准码

	你可以认为是不同的东西!
	ANSI码仅在前126个与ASCII码相同
*/
//

//
/*
/*
*   二进制、八进制、十进制、十六进制转换   16进制和字符相互转换                                                                                                     
*/
//

//
/*
	java内部是使用16bit的unicode编码(UTF-16)来表示字符串的,无论中文英文都是2字节;
	jni内部是使用UTF-8编码来表示字符串的,UTF-8是变长编码的unicode,一般ascii字符是1字节,中文是3字节;
	c/c++使用的是原始数据,ascii就是一个字节了,中文一般是GB2312编码,用两个字节来表示一个汉字。
*/
//

//
//   CodeConver.h
//

#ifndef CodeConver_H
#define CodeConver_H

namespace CodeConvert
{

	#include <stdio.h>
	#include <string.h>
	#include <windows.h>
    #include <assert.h>
	#include <jni.h>
	#include <jni_md.h>

	//   ANSI To Unicode
	//   测试通过
	wchar_t * ANSIToUnicode( const char* str )
	{
		int textlen ;
		wchar_t * result;
 
		textlen = MultiByteToWideChar( CP_ACP, 0, str,-1, NULL,0 ); 
		if (textlen ==0)
		{
			return NULL;
		}
		result = (wchar_t *)malloc((textlen+1)*sizeof(wchar_t)); 
		memset(result,0,(textlen+1)*sizeof(wchar_t)); 
		MultiByteToWideChar(CP_ACP, 0,str,-1,(LPWSTR)result,textlen ); 
		return result; 
	}

	/************************************************************************/
	//  Unicode  To ANSI(美国国家标准码)
	//  测试通过
	//  [2/8/2012 liu]
	/************************************************************************/
	char * UnicodeToANSI( const wchar_t* str )
	{
		char* result;
		int textlen;
		textlen = WideCharToMultiByte( CP_ACP, 0, str, -1, NULL, 0, NULL, NULL );
		if (textlen ==0)
		{
			return NULL;
		}
		result =(char *)malloc((textlen+1)*sizeof(char));
		memset( result, 0, sizeof(char) * ( textlen + 1 ) );
		WideCharToMultiByte( CP_ACP, 0, str, -1, result, textlen, NULL, NULL );
		return result;
	}

	/************************************************************************/
	//  UTF8 To Unicode
	//  [2/8/2012 liu]
	//  测试通过
	/************************************************************************/
	int   UTF8ToUnicode( wchar_t * &result,const char* utf8 )
	{
		int textlen ;
		textlen = MultiByteToWideChar( CP_UTF8, 0, (LPCSTR)utf8,-1, NULL,0 ); 
		if (textlen == 0)
		{
			return NULL;
		}
		result = (wchar_t *)malloc((textlen+1)*sizeof(wchar_t)); 
		memset(result,0,textlen * 2 + 2); 
		int widelen = MultiByteToWideChar(CP_UTF8, 0,(LPCSTR)utf8,-1,(LPWSTR)result,textlen ); 
		return widelen-1;

	}

	/************************************************************************/
	//  UnicodeToUTF8
	//  ????????
	//  [2/8/2012 liu]
	/************************************************************************/
	char * UnicodeToUTF8( const wchar_t* str )
	{
		char* result;
		int textlen;
		textlen = WideCharToMultiByte( CP_UTF8, 0, str, -1, NULL, 0, NULL, NULL );
		if (textlen == 0)
		{
			return NULL;
		}
		result =(char *)malloc((textlen+1)*sizeof(char));
		memset(result, 0, sizeof(char) * ( textlen + 1 ) );
		WideCharToMultiByte( CP_UTF8, 0, str, -1, result, textlen, NULL, NULL );
		return result;
	}
	/************************************************************************/
	//  宽字符 转换为 多字符  Unicode - ANSI
	//  ????????
	//  [2/8/2012 liu]
	/************************************************************************/
	char* w2m(const wchar_t* wcs)
	{
		int len;
		char* buf;
		if (wcs =NULL)
		{
			return NULL;
		}
		len =wcstombs(NULL,wcs,0);
		if (len == 0)
			return NULL;
		buf = (char *)malloc(sizeof(char)*(len+1));
		memset(buf, 0, sizeof(char) *(len+1));
		len =wcstombs(buf,wcs,len+1);
		return buf;
	}

	/************************************************************************/
	//  多字符 转换为 宽字符  ANSI - Unicode
	// 
	//  [2/8/2012 liu]
	/************************************************************************/
	wchar_t* multiByte_to_wideChar(const char* mbs)
	{
		int len;
		wchar_t* buf;
		if (mbs == NULL)
		{
			return NULL;
		}
		len =mbstowcs(NULL,mbs,0);
		if (len == 0)
			return NULL;
		buf = (wchar_t *)malloc(sizeof(wchar_t)*(len+1));
		memset(buf, 0, sizeof(wchar_t) *(len+1));
		len =mbstowcs(buf,mbs,len+1);
		return buf;
	}

	/************************************************************************/
	//  ANSI To UTF8
	//  ??????
	//  [2/8/2012 liu]
	/************************************************************************/
	char* ANSIToUTF8(const char* str)
	{
		return UnicodeToUTF8(ANSIToUnicode(str));
	}

	/************************************************************************/
	//  UTF8 To ANSI
	//  测试通过
	//  [2/8/2012 liu]
	/************************************************************************/
	char* UTF8ToANSI(const char* str)
	{
		wchar_t * temp;
		if (str == NULL)
		{
			return NULL;
		}
		UTF8ToUnicode(temp,str);
		return UnicodeToANSI(temp);
	}

	

	//  测试OK
	//  UTF8  convert to GB2312
	void UTF8ToGB2312( const char *  utf8, char * &gb2312 )
	{
		int nLen = MultiByteToWideChar( CP_UTF8, 0, utf8, -1, NULL, 0 );
		if (nLen == 0)
		{
			gb2312 = NULL;
			return ;
		}
		
		USHORT* pwszGB2312 = new USHORT[ nLen + 1 ];
		RtlZeroMemory( pwszGB2312, nLen * 2 + 2 );
		
		MultiByteToWideChar( CP_UTF8, 0, utf8, -1, pwszGB2312, nLen );
		
		nLen = WideCharToMultiByte( CP_ACP, 0, pwszGB2312, -1, NULL, 0, NULL, NULL );
		
		CHAR* pszGB2312 = new CHAR[ nLen + 1 ];
		RtlZeroMemory( pszGB2312, nLen + 1 );
		
		WideCharToMultiByte( CP_ACP, 0, pwszGB2312, -1, pszGB2312, nLen, NULL, NULL );
		
		gb2312 = pszGB2312;
		
	//  	delete [] pszGB2312;
	//  	delete [] pwszGB2312;
	}

	// GB2312 convert to UTF8
	//  测试通过
	int GB2312ToUTF8( const  char * gb2312,char * &utf8 )
	{
		int nLen1 = MultiByteToWideChar( CP_ACP, 0, gb2312, -1, NULL, 0 );
		if (nLen1 == 0)
		{
			return 0;
		}
		
		USHORT* pwszUTF8 = new USHORT[ nLen1 + 1 ];
		RtlZeroMemory( pwszUTF8, nLen1 * 2 + 2 );
		
		MultiByteToWideChar( CP_ACP, 0, gb2312, -1, pwszUTF8, nLen1 );
		
		int nLen = WideCharToMultiByte( CP_UTF8, 0, pwszUTF8, -1, NULL, 0, NULL, NULL );
		
		CHAR* pszUTF8 = new CHAR[ nLen + 1 ];
		RtlZeroMemory( pszUTF8, nLen + 1 );
		
		WideCharToMultiByte( CP_UTF8, 0, pwszUTF8, -1, pszUTF8, nLen, NULL, NULL );
		
		utf8 = pszUTF8;

		return nLen1-1;

	//	delete [] pszUTF8;
	//	delete [] pwszUTF8;
	}

	//  Gb2312 To Unicode
	//  测试通过
	int  Gb2312ToUnicode(wchar_t * &OutUnicode,const char *gb2312)
	{
		char * utf8 = NULL;
		if (gb2312==NULL)
		{
			OutUnicode = NULL;
			return 0;
		}
		GB2312ToUTF8(gb2312,utf8);
		int len = UTF8ToUnicode(OutUnicode,utf8);
		return len;
	}
    
//

    

//

     /**************************************************************************
	 *                                                                       
	 *  函数名:  HexToString                                  
	 *                                                                        
	 *  描  述:  16进制 转为 字符串                              
	 *                                                                        
	 *  参  数:  IN:const char *pHex,IN:unsigned long hexLen,
	 *           OUT:char *pByteString           
	 *                                                                        
	 *  返  回:  成功:0 ,   失败:1、2                                         
	 *  
	 *  作  者: liuguanglin      
	 *
	**************************************************************************/
	DWORD HexToString(/*IN*/  const char    * pHex,
					  /*IN*/  DWORD           hexLen,
					  /*OUT*/ char          * pByteString)
	{
		unsigned long i;
 
		if (pHex==NULL)
			return 1;
		
		if(hexLen <= 0)
			return 2;
		
		for(i=0;i<hexLen;i++)
		{
			if(((pHex[i]&0xf0)>>4)>=0 && ((pHex[i]&0xf0)>>4)<=9)
				pByteString[2*i]=((pHex[i]&0xf0)>>4)+0x30;
			else if(((pHex[i]&0xf0)>>4)>=10 && ((pHex[i]&0xf0)>>4)<=16)
				pByteString[2*i]=((pHex[i]&0xf0)>>4)+0x37;   //  小写:0x37 改为 0x57 
			
			if((pHex[i]&0x0f)>=0 && (pHex[i]&0x0f)<=9)
				pByteString[2*i+1]=(pHex[i]&0x0f)+0x30;
			else if((pHex[i]&0x0f)>=10 && (pHex[i]&0x0f)<=16)
				pByteString[2*i+1]=(pHex[i]&0x0f)+0x37;      //  小写:0x37 改为 0x57 
		}
		return 0;
	}

	/**************************************************************************
	 *                                                                       
	 *  函数名:  StringToHex                                  
	 *                                                                        
	 *  描  述:  字符串 转为 16进制                              
	 *                                                                        
	 *  参  数:  IN:const char *pHexBYTE,IN:DWORD dwStrLen,OUT:BYTE *pbHex           
	 *                                                                        
	 *  返  回:  成功:0 ,   失败:1、2                                         
	 *   
	 *  作  者: liuguanglin
	 *
	**************************************************************************/
	DWORD StringToHex(/*IN*/  const BYTE * pByteString,
					  /*IN */ DWORD        dwStrLen,
					  /*OUT*/ BYTE       * pbHex)  
	{
		DWORD i;
		DWORD dwRet;
		unsigned char * pTempBuf=NULL;
		
		if (pByteString==NULL || pbHex==NULL)
			return 1; 
		
		if(dwStrLen <= 0)
			return 2;
		
		if ((dwStrLen%2)!=0)
		{
			pTempBuf=(BYTE*)malloc(dwStrLen+2);
			pTempBuf[0]=0x30;
			memcpy(&pTempBuf[1],pByteString,sizeof(BYTE)*dwStrLen);
			dwRet=StringToHex(pTempBuf,dwStrLen+1,pbHex);
			free(pTempBuf);
			return dwRet;
		}
		else
		{ 
			for(i=0;i<dwStrLen;i++)
			{
				if(i%2==0)
				{
					if(pByteString[i]>='0' && pByteString[i]<='9')
						pbHex[i/2]=(pByteString[i]-0x30)<<4;
					else if(pByteString[i]>='a' && pByteString[i]<='f')
						pbHex[i/2]=(pByteString[i]-0x57)<<4;
					else if(pByteString[i]>='A' && pByteString[i]<='F')
						pbHex[i/2]=(pByteString[i]-0x37)<<4;
					else
						return 3;
				}
				else
				{
					if(pByteString[i]>='0' && pByteString[i]<='9')
						pbHex[i/2]|=pByteString[i]-0x30;
					else if(pByteString[i]>='a' && pByteString[i]<='f')
						pbHex[i/2]|=pByteString[i]-0x57;
					else if(pByteString[i]>='A' && pByteString[i]<='F')
						pbHex[i/2]|=pByteString[i]-0x37;
					else
						return 4;
				}
			}  
		}
		return 0;
	}

	/*****************************************
	HEX 到 ASCII 的转换函数
	入口参数: data: 转换数据的入口指针
	buffer: 转换后数据入口指针
	len : 需要转换的长度
	返回参数:转换后数据长度
	*******************************************/
	int  hex_2_ascii(char *data, char *buffer, int len)
	{
		const char ascTable[17] = {"0123456789ABCDEF"};
		char *tmp_p = buffer;
		int i, pos;
		pos = 0;
		
		for(i = 0; i < len; i++)
		{
			tmp_p[pos++] = ascTable[data[i]>>4&0x0f];
			tmp_p[pos++] = ascTable[data[i] & 0x0f];
		}
		tmp_p[pos] = '\0';
		return pos;
	}

	/*****************************************
	ASCII 到 HEX 的转换函数
	入口参数: O_data: 转换数据的入口指针,
	N_data: 转换后新数据的入口指针
	len : 需要转换的长度
	返回参数:-1: 转换失败
	其它:转换后数据长度
	注意:O_data[]数组中的数据在转换过程中会被修改。
	****************************************/
	int  ascii_2_hex(char *O_data,char *N_data, int len)
	{
		int i,j,tmp_len;
		char tmpData;
		for(i = 0; i < len; i++)
		{
			if ((O_data[i] >= '0') && (O_data[i] <= '9'))
			{
				tmpData = O_data[i] - '0';
			}
			else if ((O_data[i] >= 'A') && (O_data[i] <= 'F')) //A....F
			{
				tmpData = O_data[i] - 0x37;
			}
			else if((O_data[i] >= 'a') && (O_data[i] <= 'f')) //a....f
			{
				tmpData = O_data[i] - 0x57;
			}
			else{
				return -1;
			}
			O_data[i] = tmpData;
		}
		for(tmp_len = 0,j = 0; j < i; j+=2)
		{
			N_data[tmp_len++] = (O_data[j]<<4) | O_data[j+1];
		}
		return tmp_len;
	}



	/**************************************************************************
	 *                                                                       
	 *  函数名:  Soft_swap                                  
	 *                                                                        
	 *  描  述:  RSA密钥 倒序                             
	 *                                                                        
	 *  参  数:  IN: void *dst, IN: const void *src, IN: size_t count           
	 *                                                                        
	 *  返  回:  无                                      
	 *   
	 *  作  者: liuguanglin
	**************************************************************************/
	void Soft_swap(void *dst,const void *src,size_t count)
	{
		int i;
		unsigned char *t;
		unsigned char *q = (unsigned char *)dst;
		unsigned char *p = (unsigned char*) src;
		t = q;
		if(t == p)
		{
			q = (unsigned char *)malloc(count);
			assert(q);
		}
		for( i=0; (size_t) i<count; i++ ) q[count-1 - i] = p[i];
		if(t == p) {
			memcpy(p, q, count);
			free(q);
		}

	}
 
	//  编码转换  

	 UTF8 convert to GB2312
	VOID UTF82GB2312( /*IN*/ const char * utf8, /* OUT */ const char * gb2312 )
	{
		int nLen = MultiByteToWideChar( CP_UTF8, 0, utf8 , -1, NULL, 0 );
		
		USHORT* pwszGB2312 = new USHORT[ nLen + 1 ];
		RtlZeroMemory( pwszGB2312, nLen * 2 + 2 );
		
		MultiByteToWideChar( CP_UTF8, 0, utf8 , -1, pwszGB2312, nLen );
		
		nLen = WideCharToMultiByte( CP_ACP, 0, pwszGB2312, -1, NULL, 0, NULL, NULL );
		
		CHAR* pszGB2312 = new CHAR[ nLen + 1 ];
		RtlZeroMemory( pszGB2312, nLen + 1 );
		
		WideCharToMultiByte( CP_ACP, 0, pwszGB2312, -1, pszGB2312, nLen, NULL, NULL );
		
		gb2312 = pszGB2312;
		
		delete [] pszGB2312;
		delete [] pwszGB2312;
	}

	 GB2312 convert to UTF8
	VOID GB23122UTF8( /*IN*/ const char * gb2312, /* OUT */ const char * utf8 )
	{
		int nLen = MultiByteToWideChar( CP_ACP, 0, gb2312 , -1, NULL, 0 );
		
		USHORT* pwszUTF8 = new USHORT[ nLen + 1 ];
		RtlZeroMemory( pwszUTF8, nLen * 2 + 2 );
		
		MultiByteToWideChar( CP_ACP, 0, gb2312 , -1, pwszUTF8, nLen );
		
		nLen = WideCharToMultiByte( CP_UTF8, 0, pwszUTF8, -1, NULL, 0, NULL, NULL );
		
		CHAR* pszUTF8 = new CHAR[ nLen + 1 ];
		RtlZeroMemory( pszUTF8, nLen + 1 );
		
		WideCharToMultiByte( CP_UTF8, 0, pwszUTF8, -1, pszUTF8, nLen, NULL, NULL );
		
		utf8 = pszUTF8;
		
		delete [] pszUTF8;
		delete [] pwszUTF8;
	} 



	
//-----------------------------------------------  JNI 部分  ---------------------------------------
/*
	java内部是使用16bit的unicode编码(UTF-16)来表示字符串的,无论中文英文都是2字节;
	jni内部是使用UTF-8编码来表示字符串的,UTF-8是变长编码的unicode,一般ascii字符是1字节,中文是3字节;
	c/c++使用的是原始数据,ascii就是一个字节了,中文一般是GB2312编码,用两个字节来表示一个汉字。
*/
	



	//  测试Ok
	// 只适用于 window平台
	char* jstringToWindows( JNIEnv *env, jstring jstr )
	{ // unicode(UTF-16) 转换成 GB2312
		int length = (env)->GetStringLength(jstr );
		const jchar* jcstr = (env)->GetStringChars(jstr, 0 );
		char* rtn = (char*)malloc( length*2+1 );
		int size = 0;
		size = WideCharToMultiByte( CP_ACP, 0, (LPCWSTR)jcstr, length, rtn,(length*2+1), NULL, NULL );
		if( size <= 0 )
			return NULL;
		(env)->ReleaseStringChars(jstr, jcstr );
		rtn[size] = 0;
		return rtn;
	}


	//  测试Ok
	//  只适用于 window平台
	jstring WindowsTojstring( JNIEnv* env,const char* str )
	{	//GB2312转换成 unicode(UTF-16)
		jstring rtn = 0;
		int slen = strlen(str);
		unsigned short * buffer = 0;
		if( slen == 0 )
			rtn = (env)->NewStringUTF(str );
		else
		{
			int length = MultiByteToWideChar( CP_ACP, 0, (LPCSTR)str, slen, NULL, 0 );
			buffer = (unsigned short *)malloc( length*2 + 1 );
			if( MultiByteToWideChar( CP_ACP, 0, (LPCSTR)str, slen, (LPWSTR)buffer, length ) >0 )
			{
				rtn = (env)->NewString(  (jchar*)buffer, length );
			}
			//   rtn = (env)->NewString(  (jchar*)buffer, length );
		}
		if( buffer )
			free( buffer );
		
		return rtn;
	}


	/************************************************************************/
	//java jni中跨平台(win32或linux,unix)  String转为jstring 。                                                                     
	/************************************************************************/
	jstring nativeTojstring( JNIEnv* env,const char* str )
	{    
		jclass strClass = env->FindClass( "Ljava/lang/String;"); 
		jmethodID ctorID = env->GetMethodID( strClass, "<init>", 
			"([BLjava/lang/String;)V");
		
		if (env->ExceptionCheck() == JNI_TRUE || str == NULL)
		{
			env->ExceptionDescribe();
			env->ExceptionClear();
			printf("nativeTojstring函数转换时,str为空/n");
			return NULL;
		}
		
		jbyteArray bytes = env->NewByteArray( strlen(str)); 
		//如果str为空则抛出异常给jvm
		
		env->SetByteArrayRegion( bytes, 0,  strlen(str), (jbyte*)str); 
		jstring encoding = env->NewStringUTF( "GBK"); 
		jstring strRtn = (jstring)env->NewObject( strClass, ctorID, bytes, 
			encoding);
		//释放str内存
		// free(str);
		return strRtn;
	}

	/************************************************************************/
	//java jni中跨平台(win32或linux,unix)  jstring转为String 。                                                                     
	/************************************************************************/
	char* jstringToNative(JNIEnv *env, jstring jstr)
	{
		if (env->ExceptionCheck() == JNI_TRUE || jstr == NULL)
		{
			env->ExceptionDescribe();
			env->ExceptionClear();
			printf("jstringToNative函数转换时,传入的参数str为空");
			return NULL;
		}
		
		jbyteArray bytes = 0; 
		jthrowable exc; 
		char *result = 0; 
		if (env->EnsureLocalCapacity(2) < 0) { 
			return 0; /* out of memory error */ 
		} 
		jclass jcls_str = env->FindClass("java/lang/String"); 
		jmethodID MID_String_getBytes = env->GetMethodID(jcls_str, "getBytes", "()[B");
		
		bytes = (jbyteArray)env->CallObjectMethod(jstr, MID_String_getBytes); 
		exc = env->ExceptionOccurred(); 
		if (!exc) { 
			jint len = env->GetArrayLength( bytes); 
			result = (char *)malloc(len + 1); 
			if (result == 0) { 
				//  这个好像是要在Linux 平台下才有的函数,
				//  window 报错:error C2065: 'JNU_ThrowByName' : undeclared identifier
		//		JNU_ThrowByName(env, "java/lang/OutOfMemoryError", 0);   
				env->DeleteLocalRef(bytes); 
				return 0; 
			} 
			env->GetByteArrayRegion(bytes, 0, len, (jbyte *)result); 
			result[len] = 0; /* NULL-terminate */ 
		} else { 
			env->DeleteLocalRef(exc); 
		} 
		env->DeleteLocalRef(bytes); 
		return (char*)result;
	}

}

 
#endif


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值