Android NDK基础15:文件加解密_文件合并

文件加解密

public class Cryptor {

    public native static void crypt(String normal_path, String crypt_path);

    public native static void decrypt(String crypt_path, String decrypt_path);

    static {
        System.loadLibrary("FileCrypt");
    }

}

FileCrypt.c

#include "cn_appblog_ndkfilecrypt_Cryptor.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

char password[] = "appblog.cn";

//加密
JNIEXPORT void JNICALL Java_cn_appblog_ndkfilecrypt_Cryptor_crypt(
  JNIEnv *env, jclass jcls, jstring normal_path_jstr,jstring crypt_path_jstr) {

    //jstring -> char*
    const char* normal_path = (*env)->GetStringUTFChars(env, normal_path_jstr, JNI_FALSE);
    const char* crypt_path = (*env)->GetStringUTFChars(env, crypt_path_jstr, JNI_FALSE);

    //打开文件
    FILE *normal_fp = fopen(normal_path, "rb");
    FILE *crypt_fp = fopen(crypt_path, "wb");
    //一次读取一个字符
    int ch;
    int i = 0; //循环使用密码中的字母进行异或运算
    int pwd_len = strlen(password); //密码的长度
    while ((ch = fgetc(normal_fp)) != EOF) { //End of File
        //写入(异或运算)
        fputc(ch ^ password[i % pwd_len], crypt_fp);
        i++;
    }
    //关闭
    fclose(crypt_fp);
    fclose(normal_fp);
}

//解密
JNIEXPORT void JNICALL Java_cn_appblog_ndkfilecrypt_Cryptor_decrypt(
  JNIEnv * env, jclass jcls, jstring crypt_path_jstr, jstring decrypt_path_jstr) {

    const char* crypt_path = (*env)->GetStringUTFChars(env, crypt_path_jstr, JNI_FALSE);
    const char* decrypt_path = (*env)->GetStringUTFChars(env, decrypt_path_jstr, JNI_FALSE);

    //打开文件
    FILE *normal_fp = fopen(crypt_path, "rb");
    FILE *crypt_fp = fopen(decrypt_path, "wb");
    //一次读取一个字符
    int ch;
    int i = 0; //循环使用密码中的字母进行异或运算
    int pwd_len = strlen(password); //密码的长度
    while ((ch = fgetc(normal_fp)) != EOF) { //End of File
        //写入(异或运算)
        fputc(ch ^ password[i % pwd_len], crypt_fp);
        i++;
    }
    //关闭
    fclose(crypt_fp);
    fclose(normal_fp);
}

Application.mk

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE    := FileCrypt
LOCAL_SRC_FILES := FileCrypt.c

LOCAL_LDLIBS := -llog

include $(BUILD_SHARED_LIBRARY)

Application.mk

APP_ABI := armeabi armeabi-v7a arm64-v8a x86 x86_64 mips mips64
APP_PLATFORM := android-9

文件合并

public class FilePatch {

    /**
     * 拆分
     * @param origin_path
     * @param path_pattern
     * @param count
     */
    public native static void diff(String origin_path, String path_pattern, int count);

    /**
     * 合并
     * @param merge_path
     * @param path_pattern
     * @param count
     */
    public native static void patch(String merge_path, String path_pattern, int count);

    static{
        System.loadLibrary("FilePatch");
    }

}

FilePatch.c

#include "cn_appblog_ndkfilepatch_FilePatch.h"

#include <stdlib.h>
#include <stdio.h>

#include <android/log.h>

#ifndef  LOG
#define  LOG_TAG   "yezhou"
#define  LOGI(...)  __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
#define  LOGE(...)  __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
#endif

//获取文件大小
long get_file_size(const char *path) {
    FILE *fp = fopen(path, "rb");
    fseek(fp, 0, SEEK_END);
    return ftell(fp);
}

//拆分
JNIEXPORT void JNICALL Java_cn_appblog_ndkfilepatch_FilePatch_diff
  (JNIEnv *env, jclass jcls, jstring origin_path_jstr, jstring path_pattern_jstr, jint file_count) {
    //jstring -> char*
    //需要分割的文件路径
    const char* origin_path = (*env)->GetStringUTFChars(env, origin_path_jstr, NULL);
    const char* path_pattern = (*env)->GetStringUTFChars(env, path_pattern_jstr, NULL);

    //得到分割之后的子文件的路径列表
    char **patches = malloc(sizeof(char*) * file_count);
    int i = 0;
    for (; i < file_count; i++) {
        patches[i] = malloc(sizeof(char) * 100);
        //元素赋值
        //需要分割的文件:C://jason/liuyan.png
        //子文件:C://jason/liuyan_%d.png
        sprintf(patches[i], path_pattern, (i+1));
        LOGI("patch path:%s", patches[i]);
    }

    //不断读取path文件,循环写入file_count个文件中
    //整除
    //    文件大小:90,分成9个文件,每个文件10
    //不整除
    //    文件大小:110,分成9个文件,
    //    前(9-1)个文件为(110/(9-1))=13
    //    最后一个文件(110%(9-1))=6
    int filesize = get_file_size(origin_path);
    FILE *fpr = fopen(origin_path, "rb");
    //整除
    if(filesize % file_count == 0) {
        //单个文件大小
        int part = filesize / file_count;
        i = 0;
        //逐一写入不同的分割子文件中
        for (; i < file_count; i++) {
            FILE *fpw = fopen(patches[i], "wb");
            int j = 0;
            for(; j < part; j++) {
                //边读边写
                fputc(fgetc(fpr), fpw);
            }
            fclose(fpw);
        }
    } else {
        //不整除
        int part = filesize / (file_count-1);
        i = 0;
        //逐一写入不同的分割子文件中
        for (; i < file_count-1; i++) {
            FILE *fpw = fopen(patches[i], "wb");
            int j = 0;
            for(; j < part; j++) {
                //边读边写
                fputc(fgetc(fpr), fpw);
            }
            fclose(fpw);
        }
        //最后一个文件
        FILE *fpw = fopen(patches[file_count-1], "wb");
        i = 0;
        for(; i < filesize % (file_count-1); i++) {
            fputc(fgetc(fpr), fpw);
        }
        fclose(fpw);
    }

    //关闭被分割的文件
    fclose(fpr);

    //释放
    i = 0;
    for(; i < file_count; i++) {
        free(patches[i]);
    }
    free(patches);

    (*env)->ReleaseStringUTFChars(env, origin_path_jstr, origin_path);
    (*env)->ReleaseStringUTFChars(env, path_pattern_jstr, path_pattern);
}

//合并
JNIEXPORT void JNICALL Java_cn_appblog_ndkfilepatch_FilePatch_patch
  (JNIEnv *env, jclass jcls, jstring merge_path_jstr, jstring path_pattern_jstr, jint file_count) {
    //合并之后的文件
    const char* merge_path = (*env)->GetStringUTFChars(env, merge_path_jstr, NULL);
    //分割子文件的pattern
    const char* path_pattern = (*env)->GetStringUTFChars(env, path_pattern_jstr, NULL);

    //得到分割之后的子文件的路径列表
    char **patches = malloc(sizeof(char*) * file_count);
    int i = 0;
    for (; i < file_count; i++) {
        patches[i] = malloc(sizeof(char) * 100);
        //元素赋值
        //需要分割的文件:C://jason/liuyan.png
        //子文件:C://jason/liuyan_%d.png
        sprintf(patches[i], path_pattern, (i+1));
        LOGI("patch path:%s", patches[i]);
    }

    FILE *fpw = fopen(merge_path,"wb");
    //把所有的分割文件读取一遍,写入一个总的文件中
    i = 0;
    for(; i < file_count; i++) {
        //每个子文件的大小
        int filesize = get_file_size(patches[i]);
        FILE *fpr = fopen(patches[i], "rb");
        int j = 0;
        for (; j < filesize; j++) {
            fputc(fgetc(fpr),fpw);
        }
        fclose(fpr);
    }
    fclose(fpw);

    //释放
    i = 0;
    for(; i < file_count; i++) {
        free(patches[i]);
    }
    free(patches);

    (*env)->ReleaseStringUTFChars(env, merge_path_jstr, merge_path);
    (*env)->ReleaseStringUTFChars(env, path_pattern_jstr, path_pattern);
}

Application.mk

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE    := FilePatch
LOCAL_SRC_FILES := FilePatch.c

LOCAL_LDLIBS := -llog

include $(BUILD_SHARED_LIBRARY)

Application.mk

APP_ABI := armeabi armeabi-v7a arm64-v8a x86 x86_64 mips mips64
APP_PLATFORM := android-9

版权声明:
作者:Joe.Ye
链接:https://www.appblog.cn/index.php/2023/02/25/android-ndk-basic-file-encryption-and-decryption-file-merge/
来源:APP全栈技术分享
文章版权归作者所有,未经允许请勿转载。

THE END
分享
二维码
打赏
海报
Android NDK基础15:文件加解密_文件合并
文件加解密 public class Cryptor { public native static void crypt(String normal_path, String crypt_path); public native static void decryp……
<<上一篇
下一篇>>
文章目录
关闭
目 录