字符编码转换_进制转换(GB2312,GBK,JNI,HexTOStr)
2012-05-09 23:31
399 查看
////////////////////////////////////////////////////////////////////// /* 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
相关文章推荐
- 字符编码转换_进制转换(GB2312,GBK,JNI,HexTOStr)
- C+++Utf8字符转换Gb2312编码,解决TinyXml中文乱码
- JAVA字符编码系列二:Unicode,ISO-8859,GBK,UTF-8编码及相互转换
- java中GB2312 To Utf-8字符转换 - Java - ITeye论坛
- php字符编码转换之gb2312转为utf8
- 分享:编码转换:UTF-8 BOM to GBK
- PHP实现gb2312、UTF-8等字符和unicode间的编码转换及PHP版unescape
- 也谈字符编码 ascii gb2312 gbk gb13080 unicode utf-8 utf-16 utf-32
- 字符编码 GB2312 GBK UTF-8 区别
- 字符在utf-8,gbk,gb2312,iso8859-1下的编码实验
- WindowsPhone的中文GB2312、GBK编码与Unicode相互转换
- JAVA字符编码系列一:Unicode,GBK,GB2312,UTF-8概念基础
- 【JAVA编码专题】JAVA字符编码系列一:Unicode,GBK,GB2312,UTF-8概念基础 分类: B1_JAVA 2015-02-10 21:01 158人阅读 评论(0) 收藏
- JNI编译时错误 编码GBK的不可映射字符 解决方法
- 字符编码详解 由来(ASCII-GB2312-GBK-UNICODE-UTF-8)
- 关于JAVA字符编码:Unicode,ISO-8859-1,GBK,UTF-8编码及相互转换
- GB2312、GBK、BIG5、Unicode及字符编码基础知识
- JAVA字符编码系列二:Unicode,ISO-8859,GBK,UTF-8编码及相互转换
- 【JAVA编码专题】JAVA字符编码系列一:Unicode,GBK,GB2312,UTF-8概念基础