zoukankan      html  css  js  c++  java
  • Base64编解码Android和ios的例子,补充JNI中的例子

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

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

        使用方法如下:

       

    Java代码  收藏代码
    1. // Base64 编码:  
    2.         byte [] encode = Base64.encode("Hello, World".getBytes(), Base64.DEFAULT);  
    3.           
    4.         String enc = new String(encode);  
    5.           
    6.         Log.d("","base 64 encode = " + enc);  
    7.           
    8.         // Base64 解码:  
    9.         byte [] result = Base64.decode("SGVsbG8sIFdvcmxk", Base64.DEFAULT);  
    10.           
    11.         String res = new String(result);  
    12.           
    13.         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代码  收藏代码
    1. #include "com_example_base64test_JniTest.h"  
    2.   
    3. #include <stdlib.h>  
    4.   
    5.   
    6. #include <android/log.h> // 这个是输出LOG所用到的函数所在的路径  
    7.   
    8. #define LOG_TAG    "JNILOG" // 这个是自定义的LOG的标识  
    9. #undef LOG // 取消默认的LOG  
    10.   
    11. #define LOGD(...)  __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__) // 定义LOG类型  
    12. #define LOGI(...)  __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__) // 定义LOG类型  
    13. #define LOGW(...)  __android_log_print(ANDROID_LOG_WARN,LOG_TAG,__VA_ARGS__) // 定义LOG类型  
    14. #define LOGE(...)  __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__) // 定义LOG类型  
    15. #define LOGF(...)  __android_log_print(ANDROID_LOG_FATAL,LOG_TAG,__VA_ARGS__) // 定义LOG类型  
    16.   
    17. const char base[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";  
    18. char* base64_encode(const char* data, int data_len);  
    19. char *base64_decode(const char* data, int data_len);  
    20. static char find_pos(char ch);  
    21.   
    22.   
    23. /* 
    24.  * Class:     com_example_base64test_JniTest 
    25.  * Method:    encode 
    26.  * Signature: (Ljava/lang/String;)Ljava/lang/String; 
    27.  */  
    28. JNIEXPORT jstring JNICALL Java_com_example_base64test_JniTest_encode  
    29.   (JNIEnv *env, jobject obj, jstring string)  
    30. {  
    31.   
    32.     // 先将jstring转换成char*  
    33.     char *t = 0;  
    34.     jclass clsstring = env->FindClass("java/lang/String");  
    35.     jstring strencode = env->NewStringUTF("utf-8");  
    36.     jmethodID mid = env->GetMethodID(clsstring, "getBytes", "(Ljava/lang/String;)[B");  
    37.     jbyteArray barr= (jbyteArray)env->CallObjectMethod(string, mid, strencode);  
    38.     jsize alen = env->GetArrayLength(barr);  
    39.     jbyte* ba = env->GetByteArrayElements(barr, JNI_FALSE);  
    40.     if (alen > 0)  
    41.     {  
    42.     t = (char*)malloc(alen + 1);  
    43.     memcpy(t, ba, alen);  
    44.     t[alen] = 0;  
    45.     }  
    46.     env->ReleaseByteArrayElements(barr, ba, 0);  
    47.   
    48.     // 此时的t里面有了jstring的内容  
    49.     int i = 0;  
    50.     int j = strlen(t);  
    51.     char *enc = base64_encode(t, j);  
    52.     int len = strlen(enc);  
    53.     char *dec = base64_decode(enc, len);  
    54.     LOGD(" original: %s ", t);  
    55.     LOGD(" encoded : %s ", enc);  
    56.     LOGD(" decoded : %s ", dec);  
    57.     free(enc);  
    58.     free(dec);  
    59.   
    60.     // 将base64编码后的char转换成jstring返回给java层  
    61. //    jclass strClass = env->FindClass("Ljava/lang/String;");  
    62.     jclass strClass = env->FindClass("java/lang/String");  
    63.     jmethodID ctorID = env->GetMethodID(strClass, "<init>", "([BLjava/lang/String;)V");  
    64.     jbyteArray bytes = env->NewByteArray(strlen(enc));  
    65.     env->SetByteArrayRegion(bytes, 0, strlen(enc), (jbyte*)enc);  
    66.     jstring encoding = env->NewStringUTF("UTF-8");  
    67. //    jchar encoding_name[] = { 'U', 'T', 'F', '-', '8'};  
    68. //    jstring encoding = env->NewString(encoding_name, 5);  
    69.     return (jstring)env->NewObject(strClass, ctorID, bytes, encoding);  
    70.   
    71. //    jbyte buffer[] = /* UTF8 encoding buffer */  
    72. //  
    73. //    jbyteArray bytes = env->NewByteArray(sizeof(buffer));  
    74. //  
    75. //    env->SetByteArrayRegion(bytes, 0, sizeof(buffer), buffer);  
    76.   
    77. //    return bytes;  
    78. }  
    79.   
    80. /* 
    81.  * Class:     com_example_base64test_JniTest 
    82.  * Method:    decode 
    83.  * Signature: (Ljava/lang/String;)Ljava/lang/String; 
    84.  */  
    85. JNIEXPORT jstring JNICALL Java_com_example_base64test_JniTest_decode  
    86.   (JNIEnv *env, jobject obj, jstring base)  
    87. {  
    88.     // 先将jstring转换成char*  
    89.     char *t = 0;  
    90.     jclass clsstring = env->FindClass("java/lang/String");  
    91.     jstring strencode = env->NewStringUTF("utf-8");  
    92.     jmethodID mid = env->GetMethodID(clsstring, "getBytes", "(Ljava/lang/String;)[B");  
    93.     jbyteArray barr= (jbyteArray)env->CallObjectMethod(base, mid, strencode);  
    94.     jsize alen = env->GetArrayLength(barr);  
    95.     jbyte* ba = env->GetByteArrayElements(barr, JNI_FALSE);  
    96.     if (alen > 0)  
    97.     {  
    98.     t = (char*)malloc(alen + 1);  
    99.     memcpy(t, ba, alen);  
    100.     t[alen] = 0;  
    101.     }  
    102.     env->ReleaseByteArrayElements(barr, ba, 0);  
    103.   
    104.     // 此时的t里面有了jstring的内容  
    105.     int i = 0;  
    106.     int j = strlen(t);  
    107. //    char *enc = base64_encode(t, j);  
    108. //    int len = strlen(enc);  
    109.     char *dec = base64_decode(t, j);  
    110.     LOGD(" original: %s ", t);  
    111. //    LOGD(" encoded : %s ", enc);  
    112.     LOGD(" decoded : %s ", dec);  
    113. //    free(enc);  
    114.     free(dec);  
    115.   
    116.     // 将base64编码后的char转换成jstring返回给java层  
    117. //    jclass strClass = env->FindClass("Ljava/lang/String;");  
    118.     jclass strClass = env->FindClass("java/lang/String");  
    119.     jmethodID ctorID = env->GetMethodID(strClass, "<init>", "([BLjava/lang/String;)V");  
    120.     jbyteArray bytes = env->NewByteArray(strlen(dec));  
    121.     env->SetByteArrayRegion(bytes, 0, strlen(dec), (jbyte*)dec);  
    122.     jstring encoding = env->NewStringUTF("utf-8");  
    123.     jobject result = env->NewObject(strClass, ctorID, bytes, encoding);  
    124.     return (jstring)env->NewObject(strClass, ctorID, bytes, encoding);  
    125. //    return result;  
    126. //    return bytes;  
    127. }  
    128.   
    129. /* */  
    130. char *base64_encode(const char* data, int data_len)  
    131. {  
    132.     //int data_len = strlen(data);  
    133.     int prepare = 0;  
    134.     int ret_len;  
    135.     int temp = 0;  
    136.     char *ret = NULL;  
    137.     char *f = NULL;  
    138.     int tmp = 0;  
    139.     char changed[4];  
    140.     int i = 0;  
    141.     ret_len = data_len / 3;  
    142.     temp = data_len % 3;  
    143.     if (temp > 0)  
    144.     {  
    145.         ret_len += 1;  
    146.     }  
    147.     ret_len = ret_len*4 + 1;  
    148.     ret = (char *)malloc(ret_len);  
    149.   
    150.     if ( ret == NULL)  
    151.     {  
    152.         LOGD("No enough memory. ");  
    153.         exit(0);  
    154.     }  
    155.     memset(ret, 0, ret_len);  
    156.     f = ret;  
    157.     while (tmp < data_len)  
    158.     {  
    159.         temp = 0;  
    160.         prepare = 0;  
    161.         memset(changed, '', 4);  
    162.         while (temp < 3)  
    163.         {  
    164.             //printf("tmp = %d ", tmp);  
    165.             if (tmp >= data_len)  
    166.             {  
    167.                 break;  
    168.             }  
    169.             prepare = ((prepare << 8) | (data[tmp] & 0xFF));  
    170.             tmp++;  
    171.             temp++;  
    172.         }  
    173.         prepare = (prepare<<((3-temp)*8));  
    174.         //printf("before for : temp = %d, prepare = %d ", temp, prepare);  
    175.         for (i = 0; i < 4 ;i++ )  
    176.         {  
    177.             if (temp < i)  
    178.             {  
    179.                 changed[i] = 0x40;  
    180.             }  
    181.             else  
    182.             {  
    183.                 changed[i] = (prepare>>((3-i)*6)) & 0x3F;  
    184.             }  
    185.             *f = base[changed[i]];  
    186.             //printf("%.2X", changed[i]);  
    187.             f++;  
    188.         }  
    189.     }  
    190.     *f = '';  
    191.   
    192.     return ret;  
    193.   
    194. }  
    195. /* */  
    196. static char find_pos(char ch)  
    197. {  
    198.     char *ptr = (char*)strrchr(base, ch);//the last position (the only) in base[]  
    199.     return (ptr - base);  
    200. }  
    201. /* */  
    202. char *base64_decode(const char *data, int data_len)  
    203. {  
    204.     int ret_len = (data_len / 4) * 3;  
    205.     int equal_count = 0;  
    206.     char *ret = NULL;  
    207.     char *f = NULL;  
    208.     int tmp = 0;  
    209.     int temp = 0;  
    210.     char need[3];  
    211.     int prepare = 0;  
    212.     int i = 0;  
    213.     if (*(data + data_len - 1) == '=')  
    214.     {  
    215.         equal_count += 1;  
    216.     }  
    217.     if (*(data + data_len - 2) == '=')  
    218.     {  
    219.         equal_count += 1;  
    220.     }  
    221.     if (*(data + data_len - 3) == '=')  
    222.     {//seems impossible  
    223.         equal_count += 1;  
    224.     }  
    225.     switch (equal_count)  
    226.     {  
    227.     case 0:  
    228.         ret_len += 4;//3 + 1 [1 for NULL]  
    229.         break;  
    230.     case 1:  
    231.         ret_len += 4;//Ceil((6*3)/8)+1  
    232.         break;  
    233.     case 2:  
    234.         ret_len += 3;//Ceil((6*2)/8)+1  
    235.         break;  
    236.     case 3:  
    237.         ret_len += 2;//Ceil((6*1)/8)+1  
    238.         break;  
    239.     }  
    240.     ret = (char *)malloc(ret_len);  
    241.     if (ret == NULL)  
    242.     {  
    243.         LOGD("No enough memory. ");  
    244.         exit(0);  
    245.     }  
    246.     memset(ret, 0, ret_len);  
    247.     f = ret;  
    248.     while (tmp < (data_len - equal_count))  
    249.     {  
    250.         temp = 0;  
    251.         prepare = 0;  
    252.         memset(need, 0, 4);  
    253.         while (temp < 4)  
    254.         {  
    255.             if (tmp >= (data_len - equal_count))  
    256.             {  
    257.                 break;  
    258.             }  
    259.             prepare = (prepare << 6) | (find_pos(data[tmp]));  
    260.             temp++;  
    261.             tmp++;  
    262.         }  
    263.         prepare = prepare << ((4-temp) * 6);  
    264.         for (i=0; i<3 ;i++ )  
    265.         {  
    266.             if (i == temp)  
    267.             {  
    268.                 break;  
    269.             }  
    270.             *f = (char)((prepare>>((2-i)*8)) & 0xFF);  
    271.             f++;  
    272.         }  
    273.     }  
    274.     *f = '';  
    275.     return ret;  
    276. }  

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

  • 相关阅读:
    mysql采坑笔记
    git常用操作
    vscode配置及插件
    atom之插件安装及相关
    xshell中操作服务器笔记
    js学习笔记之自调用函数、闭包、原型链
    dragover event 翻译
    拖放事件笔记
    关于clear:both;后有固定高度的原因及解决方法
    weex打包android apk采坑之旅(windows)
  • 原文地址:https://www.cnblogs.com/pansly/p/3867772.html
Copyright © 2011-2022 走看看