jni 调用java base64_Base64编解码Android和ios的例子,补充JNI中的例子

1.在Android中java层提供了工具类:android.util.Base64;

里面都是静态方法,方便直接使用:

使用方法如下:

Java代码  b1e9480a4729cb4002d50bb44aab00ac.png

// 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代码  b1e9480a4729cb4002d50bb44aab00ac.png

#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层的确是乱码,这个问题暂时还没有解决。希望有明白的同志告知一下。谢谢。工程附件中。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值