您的位置:首页 > 其它

字符编码转换_进制转换(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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: