1.在Android中java层提供了工具类:android.util.Base64;
里面都是静态方法,方便直接使用:
使用方法如下:
Java代码
// Base64 编码:
byte [] encode = Base64.encode("Hello, World".getBytes(), Base64.DEFAULT);
String enc = new String(encode);
Log.d("","base 64 encode = " + enc);
// Base64 解码:
byte [] result = Base64.decode("SGVsbG8sIFdvcmxk", Base64.DEFAULT);
String res = new String(result);
Log.d("", "base 64 result = " + 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 = [GTMBase64 encodeData:data];
NSString *base64String = [[NSStringalloc] initWithData:dataencoding:NSUTF8StringEncoding];
return base64String;
}
- (NSString *) decodeBase64:(NSString *) input{
NSData *data = [inputdataUsingEncoding:NSUTF8StringEncodingallowLossyConversion:YES];
data = [GTMBase64 decodeData:data];
NSString *string = [[NSStringalloc] initWithData:dataencoding:NSUTF8StringEncoding];
return string;
}
3.在Android中,我们也可以将base64的编解码算法放到jni中,这样也是比较方便的。
对应的c中算法如下:
C代码
#include "com_example_base64test_JniTest.h"
#include
#include // 这个是输出LOG所用到的函数所在的路径
#define LOG_TAG "JNILOG" // 这个是自定义的LOG的标识
#undef LOG // 取消默认的LOG
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__) // 定义LOG类型
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__) // 定义LOG类型
#define LOGW(...) __android_log_print(ANDROID_LOG_WARN,LOG_TAG,__VA_ARGS__) // 定义LOG类型
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__) // 定义LOG类型
#define LOGF(...) __android_log_print(ANDROID_LOG_FATAL,LOG_TAG,__VA_ARGS__) // 定义LOG类型
const char base[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
char* base64_encode(const char* data, int data_len);
char *base64_decode(const char* data, int data_len);
static char find_pos(char ch);
/*
* Class: com_example_base64test_JniTest
* Method: encode
* Signature: (Ljava/lang/String;)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_example_base64test_JniTest_encode
(JNIEnv *env, jobject obj, jstring string)
{
// 先将jstring转换成char*
char *t = 0;
jclass clsstring = env->FindClass("java/lang/String");
jstring strencode = env->NewStringUTF("utf-8");
jmethodID mid = env->GetMethodID(clsstring, "getBytes", "(Ljava/lang/String;)[B");
jbyteArray barr= (jbyteArray)env->CallObjectMethod(string, mid, strencode);
jsize alen = 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的内容
int i = 0;
int j = strlen(t);
char *enc = base64_encode(t, j);
int len = 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层
// jclass strClass = env->FindClass("Ljava/lang/String;");
jclass strClass = env->FindClass("java/lang/String");
jmethodID ctorID = env->GetMethodID(strClass, "", "([BLjava/lang/String;)V");
jbyteArray bytes = env->NewByteArray(strlen(enc));
env->SetByteArrayRegion(bytes, 0, strlen(enc), (jbyte*)enc);
jstring encoding = env->NewStringUTF("UTF-8");
// jchar encoding_name[] = { 'U', 'T', 'F', '-', '8'};
// jstring encoding = env->NewString(encoding_name, 5);
return (jstring)env->NewObject(strClass, ctorID, bytes, encoding);
// jbyte buffer[] = /* UTF8 encoding buffer */
//
// jbyteArray bytes = env->NewByteArray(sizeof(buffer));
//
// env->SetByteArrayRegion(bytes, 0, sizeof(buffer), buffer);
// return bytes;
}
/*
* Class: com_example_base64test_JniTest
* Method: decode
* Signature: (Ljava/lang/String;)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_example_base64test_JniTest_decode
(JNIEnv *env, jobject obj, jstring base)
{
// 先将jstring转换成char*
char *t = 0;
jclass clsstring = env->FindClass("java/lang/String");
jstring strencode = env->NewStringUTF("utf-8");
jmethodID mid = env->GetMethodID(clsstring, "getBytes", "(Ljava/lang/String;)[B");
jbyteArray barr= (jbyteArray)env->CallObjectMethod(base, mid, strencode);
jsize alen = 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的内容
int i = 0;
int j = strlen(t);
// char *enc = base64_encode(t, j);
// int len = 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层
// jclass strClass = env->FindClass("Ljava/lang/String;");
jclass strClass = env->FindClass("java/lang/String");
jmethodID ctorID = env->GetMethodID(strClass, "", "([BLjava/lang/String;)V");
jbyteArray bytes = env->NewByteArray(strlen(dec));
env->SetByteArrayRegion(bytes, 0, strlen(dec), (jbyte*)dec);
jstring encoding = env->NewStringUTF("utf-8");
jobject result = env->NewObject(strClass, ctorID, bytes, encoding);
return (jstring)env->NewObject(strClass, ctorID, bytes, encoding);
// return result;
// return bytes;
}
/* */
char *base64_encode(const char* data, int data_len)
{
//int data_len = strlen(data);
int prepare = 0;
int ret_len;
int temp = 0;
char *ret = NULL;
char *f = NULL;
int tmp = 0;
char changed[4];
int i = 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("No enough memory.\n");
exit(0);
}
memset(ret, 0, ret_len);
f = ret;
while (tmp
{
temp = 0;
prepare = 0;
memset(changed, '\0', 4);
while (temp
{
//printf("tmp = %d\n", tmp);
if (tmp >= data_len)
{
break;
}
prepare = ((prepare <
tmp++;
temp++;
}
prepare = (prepare<
//printf("before for : temp = %d, prepare = %d\n", temp, prepare);
for (i = 0; i
{
if (temp
{
changed[i] = 0x40;
}
else
{
changed[i] = (prepare>>((3-i)*6)) & 0x3F;
}
*f = base[changed[i]];
//printf("%.2X", changed[i]);
f++;
}
}
*f = '\0';
return ret;
}
/* */
static char find_pos(char ch)
{
char *ptr = (char*)strrchr(base, ch);//the last position (the only) in base[]
return (ptr - base);
}
/* */
char *base64_decode(const char *data, int data_len)
{
int ret_len = (data_len / 4) * 3;
int equal_count = 0;
char *ret = NULL;
char *f = NULL;
int tmp = 0;
int temp = 0;
char need[3];
int prepare = 0;
int i = 0;
if (*(data + data_len - 1) == '=')
{
equal_count += 1;
}
if (*(data + data_len - 2) == '=')
{
equal_count += 1;
}
if (*(data + data_len - 3) == '=')
{//seems impossible
equal_count += 1;
}
switch (equal_count)
{
case 0:
ret_len += 4;//3 + 1 [1 for NULL]
break;
case 1:
ret_len += 4;//Ceil((6*3)/8)+1
break;
case 2:
ret_len += 3;//Ceil((6*2)/8)+1
break;
case 3:
ret_len += 2;//Ceil((6*1)/8)+1
break;
}
ret = (char *)malloc(ret_len);
if (ret == NULL)
{
LOGD("No enough memory.\n");
exit(0);
}
memset(ret, 0, ret_len);
f = ret;
while (tmp
{
temp = 0;
prepare = 0;
memset(need, 0, 4);
while (temp
{
if (tmp >= (data_len - equal_count))
{
break;
}
prepare = (prepare <
temp++;
tmp++;
}
prepare = prepare <
for (i=0; i<3 ;i++ )
{
if (i == temp)
{
break;
}
*f = (char)((prepare>>((2-i)*8)) & 0xFF);
f++;
}
}
*f = '\0';
return ret;
}
不过这个例子里面,log打印的都是正确的,可是返回到java层的确是乱码,这个问题暂时还没有解决。希望有明白的同志告知一下。谢谢。工程附件中。