`
dingran
  • 浏览: 376254 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Base64编解码Android和ios的例子,补充JNI中的例子

 
阅读更多

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

 

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

 

    使用方法如下:

 

   

// 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 = [input dataUsingEncoding:NSUTF8StringEncodingallowLossyConversion:YES];

    data = [GTMBase64 encodeData:data];

    NSString *base64String = [[NSStringalloc] initWithData:data encoding:NSUTF8StringEncoding];

    return base64String;

}

 

- (NSString *) decodeBase64:(NSString *) input{

    NSData *data = [input dataUsingEncoding:NSUTF8StringEncodingallowLossyConversion:YES];

    data = [GTMBase64 decodeData:data];

    NSString *string = [[NSStringalloc] initWithData:data encoding:NSUTF8StringEncoding];

    return string;

}

 

3.在Android中,我们也可以将base64的编解码算法放到jni中,这样也是比较方便的。

  

   对应的c中算法如下:

 

  

#include "com_example_base64test_JniTest.h"

#include <stdlib.h>


#include <android/log.h> // 这个是输出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, "<init>", "([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, "<init>", "([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 < 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("before for : 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';

    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 < (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';
    return ret;
}

 

    不过这个例子里面,log打印的都是正确的,可是返回到java层的确是乱码,这个问题暂时还没有解决。希望有明白的同志告知一下。谢谢。工程附件中。

 

 

 

分享到:
评论

相关推荐

    android jni base64 和java base64 通用

    总之,本主题涉及了Android应用开发中的JNI技术,如何在C/C++中实现Base64编码和解码,并确保与Java的Base64实现兼容。这有助于优化性能,特别是在处理大量二进制数据时,因为本地代码通常比Java代码执行得更快。...

    android studio JNI RSA DES AES base64 MD5 加解密.rar

    本资源提供了在Android Studio项目中使用JNI实现RSA、DES、AES以及Base64和MD5的示例。 1. **RSA**: RSA是一种非对称加密算法,它基于两个密钥——公钥和私钥。公钥可以公开,用于加密数据;而私钥必须保密,用于...

    Android JNI 调用 Silk 音频编解码包

    总之,Android JNI调用Silk音频编解码包涉及到Android NDK的使用,JNI接口的创建,以及与Android音频系统的集成。通过这一过程,你可以充分利用Silk编解码器的性能优势,为你的应用提供高质量的音频处理功能。

    android JNI RSA 3DES BASE64 加解密实现

    本教程主要涉及的是在Android平台上通过JNI(Java Native Interface)使用RSA、3DES和BASE64算法进行加解密操作,这些技术都是在Native层实现的,以提供更高的性能和安全性。 首先,我们来了解这些加密算法: 1. *...

    androidjni实现本地加解密数据,使用C++语言编写,基于openssl实现 集成RSAAES3DESBASE64MD5

    本项目主要探讨了如何使用C++语言通过JNI(Java Native Interface)与Android应用交互,实现基于OpenSSL库的加解密算法,包括RSA、AES、3DES、BASE64和MD5。以下是关于这些技术的详细解释: 1. **JNI(Java Native ...

    android opus语音编解码库的生成和应用

    在Android平台上,Opus是一...总之,Opus编解码库的生成和应用是Android开发中的一个重要环节,尤其对于需要高质量实时音频传输的应用来说。正确地配置和使用Opus,能够显著提升用户体验,并为开发者提供更多的可能性。

    Android中调用JNI例子

    在Android开发中,JNI(Java Native Interface)是一个关键的技术,它允许Java代码和其他语言写的代码进行交互。JNI在很多场景下被使用,如优化性能、使用硬件特性、调用C/C++库等。本示例将详细介绍如何在Android...

    Android 上可用的G711编解码库

    在Android平台上,G711编解码库是用于处理音频数据的一种重要工具,尤其在语音通信和多媒体应用中起到关键作用。G.711是一种广泛使用的脉冲编码调制(Pulse Code Modulation,PCM)标准,分为两种模式:μ-law(u-...

    Android硬解码 media_jni.so 源码

    在Android系统中,硬解码是一项关键功能,它利用设备硬件加速来处理视频解码,以提高性能并降低功耗。MediaCodec是Android系统提供的一个API接口,用于处理媒体编码和解码。在这个主题中,我们将深入探讨与`media_...

    H264解码器(Android JNI 定制)

    这里,我们关注的是一个特定的定制版本,它利用了Android的JNI(Java Native Interface)技术来实现H264视频流的解码。这个解码器已经通过了Android 4.2和4.1版本的测试,这意味着它可以在这些早期版本的Android设备...

    I2CJNI.rar_Android jni_android_android i2c_android i2c通信 JNI_i2c

    在Android系统中,JNI(Java Native Interface)是一种技术,它允许Java代码和其他语言写的代码进行交互。本资源"I2CJNI.rar"似乎包含了一个实际应用的Android I2C通信示例,利用JNI来实现硬件级别的低层通信。I2C...

    Android JNI串口通讯【实战例子】

    Android JNI串口通讯【实战例子】 学习NDK开发很好的例子,也可以直接用在项目中

    Android C、Java、JNI效率测试结果.doc

    Android C、Java、JNI效率测试结果分析 Android 操作系统中,效率...本文档对 Android G1 环境中 C、Java、JNI 调用效率测试结果进行了详细的分析和讨论,结果表明,JNI 调用效率非常高,适合在 Android 环境中使用。

    JniCallback.zip_Android jni_android_jni android_jni callback_jni

    在Android开发中,JNI(Java Native Interface)是一个关键的技术,它允许Java代码和其他语言写的代码进行交互。JNI在很多场景下都非常有用,比如优化性能、使用现有的C/C++库、或者像在这个“JniCallback.zip”文件...

    Android--JNI-Device.zip_Android jni_android_jni_jni android

    通过分析描述和标签,我们可以深入探讨JNI在Android中的应用以及如何利用它来调用驱动代码。 1. **JNI基本概念**:JNI是Java平台的一部分,提供了一个标准的方式,让Java代码可以调用本地(native)代码,同时也...

    android下一个jni方式实现的音频播放

    在Android开发中,JNI(Java Native Interface)是一个关键的技术,它允许Java代码和其他语言写的代码进行交互。本示例着重于使用JNI在Android系统中实现音频的播放功能,这是一个深入理解Android NDK(Native ...

    android--JNI.zip_android_android 驱动_jni_jni android

    Android JNI,全称为Java Native Interface,是Android系统中用于连接Java层和原生代码(C/C++)的一个关键技术。JNI允许开发者在Android应用中调用本地方法,从而利用C和C++的强大性能和库来解决特定问题,比如优化...

    安卓串口Socket通讯USB驱动jni相关-Android中调用JNI例子.rar

    这个压缩包“安卓串口Socket通讯USB驱动jni相关-Android中调用JNI例子.rar”似乎包含了一个示例项目,展示了如何在Android应用中使用JNI来实现串口、Socket通信以及USB驱动的交互。以下将详细介绍这些知识点。 1. *...

Global site tag (gtag.js) - Google Analytics