Base64编解码Android和ios的例子,补充JNI中的例子
1.在Android中java层提供了工具类:android.util.Base64;
里面都是静态方法,方便直接使用:
使用方法如下:
Java代码- //Base64编码:
- byte[]encode=Base64.encode("Hello,World".getBytes(),Base64.DEFAULT);
- Stringenc=newString(encode);
- Log.d("","base64encode="+enc);
- //Base64解码:
- byte[]result=Base64.decode("SGVsbG8sIFdvcmxk",Base64.DEFAULT);
- Stringres=newString(result);
- Log.d("","base64result="+res);
例子演示了将"Hello, World"编码成"SGVsbG8sIFdvcmxk",然后又解码回来。简单易懂。
2.对于ios来说,有google的提供的一个工具箱来解决。
网址:http://code.google.com/p/google-toolbox-for-mac/
需要从里面找出3个文件:GTMBase64.h,GTMBase64.m,GTMDefines.h
将这三个文件加入ios工程中即可使用了。
例如:
使用:
NSLog(@"%@", [selfencodeBase64:@"Hello, World"]);
NSLog(@"%@", [selfdecodeBase64:@"SGVsbG8sIFdvcmxk"]);
调用的自己封装的函数:
- (NSString*) encodeBase64:(NSString*) input{
NSData*data = [inputdataUsingEncoding:NSUTF8StringEncodingallowLossyConversion:YES];
data = [GTMBase64encodeData:data];
NSString*base64String = [[NSStringalloc]initWithData:dataencoding:NSUTF8StringEncoding];
returnbase64String;
}
- (NSString*) decodeBase64:(NSString*) input{
NSData*data = [inputdataUsingEncoding:NSUTF8StringEncodingallowLossyConversion:YES];
data = [GTMBase64decodeData:data];
NSString*string = [[NSStringalloc]initWithData:dataencoding:NSUTF8StringEncoding];
returnstring;
}
3.在Android中,我们也可以将base64的编解码算法放到jni中,这样也是比较方便的。
对应的c中算法如下:
C代码- #include"com_example_base64test_JniTest.h"
- #include<stdlib.h>
- #include<android/log.h>//这个是输出LOG所用到的函数所在的路径
- #defineLOG_TAG"JNILOG"//这个是自定义的LOG的标识
- #undefLOG//取消默认的LOG
- #defineLOGD(...)__android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__)//定义LOG类型
- #defineLOGI(...)__android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)//定义LOG类型
- #defineLOGW(...)__android_log_print(ANDROID_LOG_WARN,LOG_TAG,__VA_ARGS__)//定义LOG类型
- #defineLOGE(...)__android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)//定义LOG类型
- #defineLOGF(...)__android_log_print(ANDROID_LOG_FATAL,LOG_TAG,__VA_ARGS__)//定义LOG类型
- constcharbase[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
- char*base64_encode(constchar*data,intdata_len);
- char*base64_decode(constchar*data,intdata_len);
- staticcharfind_pos(charch);
- /*
- *Class:com_example_base64test_JniTest
- *Method:encode
- *Signature:(Ljava/lang/String;)Ljava/lang/String;
- */
- JNIEXPORTjstringJNICALLJava_com_example_base64test_JniTest_encode
- (JNIEnv*env,jobjectobj,jstringstring)
- {
- //先将jstring转换成char*
- char*t=0;
- jclassclsstring=env->FindClass("java/lang/String");
- jstringstrencode=env->NewStringUTF("utf-8");
- jmethodIDmid=env->GetMethodID(clsstring,"getBytes","(Ljava/lang/String;)[B");
- jbyteArraybarr=(jbyteArray)env->CallObjectMethod(string,mid,strencode);
- jsizealen=env->GetArrayLength(barr);
- jbyte*ba=env->GetByteArrayElements(barr,JNI_FALSE);
- if(alen>0)
- {
- t=(char*)malloc(alen+1);
- memcpy(t,ba,alen);
- t[alen]=0;
- }
- env->ReleaseByteArrayElements(barr,ba,0);
- //此时的t里面有了jstring的内容
- inti=0;
- intj=strlen(t);
- char*enc=base64_encode(t,j);
- intlen=strlen(enc);
- char*dec=base64_decode(enc,len);
- LOGD("\noriginal:%s\n",t);
- LOGD("\nencoded:%s\n",enc);
- LOGD("\ndecoded:%s\n",dec);
- free(enc);
- free(dec);
- //将base64编码后的char转换成jstring返回给java层
- //jclassstrClass=env->FindClass("Ljava/lang/String;");
- jclassstrClass=env->FindClass("java/lang/String");
- jmethodIDctorID=env->GetMethodID(strClass,"<init>","([BLjava/lang/String;)V");
- jbyteArraybytes=env->NewByteArray(strlen(enc));
- env->SetByteArrayRegion(bytes,0,strlen(enc),(jbyte*)enc);
- jstringencoding=env->NewStringUTF("UTF-8");
- //jcharencoding_name[]={'U','T','F','-','8'};
- //jstringencoding=env->NewString(encoding_name,5);
- return(jstring)env->NewObject(strClass,ctorID,bytes,encoding);
- //jbytebuffer[]=/*UTF8encodingbuffer*/
- //
- //jbyteArraybytes=env->NewByteArray(sizeof(buffer));
- //
- //env->SetByteArrayRegion(bytes,0,sizeof(buffer),buffer);
- //returnbytes;
- }
- /*
- *Class:com_example_base64test_JniTest
- *Method:decode
- *Signature:(Ljava/lang/String;)Ljava/lang/String;
- */
- JNIEXPORTjstringJNICALLJava_com_example_base64test_JniTest_decode
- (JNIEnv*env,jobjectobj,jstringbase)
- {
- //先将jstring转换成char*
- char*t=0;
- jclassclsstring=env->FindClass("java/lang/String");
- jstringstrencode=env->NewStringUTF("utf-8");
- jmethodIDmid=env->GetMethodID(clsstring,"getBytes","(Ljava/lang/String;)[B");
- jbyteArraybarr=(jbyteArray)env->CallObjectMethod(base,mid,strencode);
- jsizealen=env->GetArrayLength(barr);
- jbyte*ba=env->GetByteArrayElements(barr,JNI_FALSE);
- if(alen>0)
- {
- t=(char*)malloc(alen+1);
- memcpy(t,ba,alen);
- t[alen]=0;
- }
- env->ReleaseByteArrayElements(barr,ba,0);
- //此时的t里面有了jstring的内容
- inti=0;
- intj=strlen(t);
- //char*enc=base64_encode(t,j);
- //intlen=strlen(enc);
- char*dec=base64_decode(t,j);
- LOGD("\noriginal:%s\n",t);
- //LOGD("\nencoded:%s\n",enc);
- LOGD("\ndecoded:%s\n",dec);
- //free(enc);
- free(dec);
- //将base64编码后的char转换成jstring返回给java层
- //jclassstrClass=env->FindClass("Ljava/lang/String;");
- jclassstrClass=env->FindClass("java/lang/String");
- jmethodIDctorID=env->GetMethodID(strClass,"<init>","([BLjava/lang/String;)V");
- jbyteArraybytes=env->NewByteArray(strlen(dec));
- env->SetByteArrayRegion(bytes,0,strlen(dec),(jbyte*)dec);
- jstringencoding=env->NewStringUTF("utf-8");
- jobjectresult=env->NewObject(strClass,ctorID,bytes,encoding);
- return(jstring)env->NewObject(strClass,ctorID,bytes,encoding);
- //returnresult;
- //returnbytes;
- }
- /**/
- char*base64_encode(constchar*data,intdata_len)
- {
- //intdata_len=strlen(data);
- intprepare=0;
- intret_len;
- inttemp=0;
- char*ret=NULL;
- char*f=NULL;
- inttmp=0;
- charchanged[4];
- inti=0;
- ret_len=data_len/3;
- temp=data_len%3;
- if(temp>0)
- {
- ret_len+=1;
- }
- ret_len=ret_len*4+1;
- ret=(char*)malloc(ret_len);
- if(ret==NULL)
- {
- LOGD("Noenoughmemory.\n");
- exit(0);
- }
- memset(ret,0,ret_len);
- f=ret;
- while(tmp<data_len)
- {
- temp=0;
- prepare=0;
- memset(changed,'\0',4);
- while(temp<3)
- {
- //printf("tmp=%d\n",tmp);
- if(tmp>=data_len)
- {
- break;
- }
- prepare=((prepare<<8)|(data[tmp]&0xFF));
- tmp++;
- temp++;
- }
- prepare=(prepare<<((3-temp)*8));
- //printf("beforefor:temp=%d,prepare=%d\n",temp,prepare);
- for(i=0;i<4;i++)
- {
- if(temp<i)
- {
- changed[i]=0x40;
- }
- else
- {
- changed[i]=(prepare>>((3-i)*6))&0x3F;
- }
- *f=base[changed[i]];
- //printf("%.2X",changed[i]);
- f++;
- }
- }
- *f='\0';
- returnret;
- }
- /**/
- staticcharfind_pos(charch)
- {
- char*ptr=(char*)strrchr(base,ch);//thelastposition(theonly)inbase[]
- return(ptr-base);
- }
- /**/
- char*base64_decode(constchar*data,intdata_len)
- {
- intret_len=(data_len/4)*3;
- intequal_count=0;
- char*ret=NULL;
- char*f=NULL;
- inttmp=0;
- inttemp=0;
- charneed[3];
- intprepare=0;
- inti=0;
- if(*(data+data_len-1)=='=')
- {
- equal_count+=1;
- }
- if(*(data+data_len-2)=='=')
- {
- equal_count+=1;
- }
- if(*(data+data_len-3)=='=')
- {//seemsimpossible
- equal_count+=1;
- }
- switch(equal_count)
- {
- case0:
- ret_len+=4;//3+1[1forNULL]
- break;
- case1:
- ret_len+=4;//Ceil((6*3)/8)+1
- break;
- case2:
- ret_len+=3;//Ceil((6*2)/8)+1
- break;
- case3:
- ret_len+=2;//Ceil((6*1)/8)+1
- break;
- }
- ret=(char*)malloc(ret_len);
- if(ret==NULL)
- {
- LOGD("Noenoughmemory.\n");
- exit(0);
- }
- memset(ret,0,ret_len);
- f=ret;
- while(tmp<(data_len-equal_count))
- {
- temp=0;
- prepare=0;
- memset(need,0,4);
- while(temp<4)
- {
- if(tmp>=(data_len-equal_count))
- {
- break;
- }
- prepare=(prepare<<6)|(find_pos(data[tmp]));
- temp++;
- tmp++;
- }
- prepare=prepare<<((4-temp)*6);
- for(i=0;i<3;i++)
- {
- if(i==temp)
- {
- break;
- }
- *f=(char)((prepare>>((2-i)*8))&0xFF);
- f++;
- }
- }
- *f='\0';
- returnret;
- }
不过这个例子里面,log打印的都是正确的,可是返回到java层的确是乱码,这个问题暂时还没有解决。希望有明白的同志告知一下。谢谢。工程附件中。
更多相关文章
- android 通信机制 socket
- Android(安卓)ServiceManager注册自定义service
- Android(安卓)最火框架XUtils之注解机制详解
- android studio里面的svn基本使用
- Base64编解码Android和ios的例子,补充JNI中的例子
- Android(安卓)自定义标签 和 自定义组件
- android Gallery实现加载网络图片
- Android(安卓)自定义像素AVD模拟器无键盘
- 2011.08.18(2)——— android 自定义组合组件 onFinishInflate onS