/*
-
Class: cn_tsou_ndkfilecrypt_ndk_Cryptor
-
Method: crypt
-
Signature: (Ljava/lang/String;Ljava/lang/String;)V
*/
JNIEXPORT void JNICALL Java_cn_tsou_ndkfilecrypt_ndk_Cryptor_crypt
(JNIEnv *, jclass, jstring, jstring);
/*
-
Class: cn_tsou_ndkfilecrypt_ndk_Cryptor
-
Method: decrypt
-
Signature: (Ljava/lang/String;Ljava/lang/String;)V
*/
JNIEXPORT void JNICALL Java_cn_tsou_ndkfilecrypt_ndk_Cryptor_decrypt
(JNIEnv *, jclass, jstring, jstring);
/*
-
Class: cn_tsou_ndkfilecrypt_ndk_Cryptor
-
Method: diff
-
Signature: (Ljava/lang/String;Ljava/lang/String;I)V
*/
JNIEXPORT void JNICALL Java_cn_tsou_ndkfilecrypt_ndk_Cryptor_diff
(JNIEnv *, jclass, jstring, jstring, jint);
/*
-
Class: cn_tsou_ndkfilecrypt_ndk_Cryptor
-
Method: path
-
Signature: (Ljava/lang/String;ILjava/lang/String;)V
*/
JNIEXPORT void JNICALL Java_cn_tsou_ndkfilecrypt_ndk_Cryptor_path
(JNIEnv *, jclass, jstring, jint, jstring);
#ifdef __cplusplus
}
#endif
#endif
- c实现类
#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include “cn_tsou_ndkfilecrypt_ndk_Cryptor.h”
#include <android/log.h>
#define LOGI(FORMAT, …) __android_log_print(ANDROID_LOG_INFO,“huangxiaoguo”,FORMAT,VA_ARGS)
#define LOGE(FORMAT, …) __android_log_print(ANDROID_LOG_ERROR,“huangxiaoguo”,FORMAT,VA_ARGS)
char password[] = “huangxiaoguo”;
//加密
JNIEXPORT void JNICALL Java_cn_tsou_ndkfilecrypt_ndk_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, NULL);
const char *crypt_path = (*env)->GetStringUTFChars(env, crypt_path_jstr, NULL);
LOGI(" path1:%s", normal_path);
LOGI(" path2:%s", crypt_path);
//打开文件
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);
(*env)->ReleaseStringUTFChars(env, normal_path_jstr, normal_path);
(*env)->ReleaseStringUTFChars(env, crypt_path_jstr, crypt_path);
}
//解密
JNIEXPORT void JNICALL Java_cn_tsou_ndkfilecrypt_ndk_Cryptor_decrypt
(JNIEnv *env, jclass jcls, jstring crypt_path_jstr, jstring decrypt_path_jstr) {
//jstring ->char*
const char *crypt_path = (*env)->GetStringUTFChars(env, crypt_path_jstr, NULL);
const char *decrypt_path = (*env)->GetStringUTFChars(env, decrypt_path_jstr, NULL);
//打开文件
FILE *crypt_fp = fopen(crypt_path, “rb”);
FILE *decrypt_fp = fopen(decrypt_path, “wb”);
//一次读取一个字符
int ch;
int i = 0;//循环使用密码中的字母进行异或运算
int pwd_len = strlen(password);//密码的长度
while ((ch = fgetc(crypt_fp)) != EOF) { //End of File
//写入(异或运算)
fputc(ch ^ password[i % pwd_len], decrypt_fp);
i++;
}
//关闭
fclose(decrypt_fp);
fclose(crypt_fp);
(*env)->ReleaseStringUTFChars(env, crypt_path_jstr, crypt_path);
(*env)->ReleaseStringUTFChars(env, decrypt_path_jstr, decrypt_path);
}
//获取文件大小
int get_file_size(char *path) {
FILE *fp = fopen(path, “rb”);
fseek(fp, 0, SEEK_END);
return ftell(fp);
}
//拆分
JNIEXPORT void JNICALL Java_cn_tsou_ndkfilecrypt_ndk_Cryptor_diff
(JNIEnv *env, jclass jcls, jstring path_jstr, jstring path_pattern_jstr, jint file_num) {
//jstring ->char*
//需要分割的文件路径
const char *path = (*env)->GetStringUTFChars(env, path_jstr, NULL);
const char *path_pattern = (*env)->GetStringUTFChars(env, path_pattern_jstr, NULL);
//得到分割之后的子文件路径列表
char **pathches = malloc(sizeof(char *) * file_num);
int i = 0;
//不断读取path文件,循环写入file_num个文件中
for (; i < file_num; ++i) {
pathches[i] = malloc(sizeof(char) * 100);
//元素赋值
//需要分割的文件:C://jason/001.jpg
// 子文件:C://jason/001_%d.jpg
sprintf(pathches[i], path_pattern, (i + 1));
LOGI(“patch path:%s”, pathches[i]);
}
/**
-
整除:
-
文件大小:90,分成9个文件,每个文件10
-
-
不整除:
-
文件大小:110,分成9个文件,
-
前(9-1)个文件为(110/(9-1))=13
-
最后一个文件(110%(9-1))=6
-
(这个逻辑有问题104出现最后一个文件为0的问题,可自行判断)
*/
int filesize = get_file_size(path);
FILE *fpr = fopen(path, “rb”);
//整除
if (filesize % file_num == 0) {
//单个文件大小
int part = filesize / file_num;
i = 0;
//逐一写入不同的分割子文件中
for (; i < file_num; ++i) {
FILE *fpw = fopen(pathches[i], “wb”);
int j = 0;
for (; j < part; ++j) {
//边读编写
fputc(fgetc(fpr), fpw);
}
fclose(fpw);
}
} else {
//不能整除
int part = filesize / (file_num - 1);
i = 0;
//逐一写入不同的分割子文件中
for (; i < file_num - 1; ++i) {
FILE *fpw = fopen(pathches[i], “wb”);
int j = 0;
for (; j < part; ++j) {
//边读编写
fputc(fgetc(fpr), fpw);
}
fclose(fpw);
}
//最后一个
FILE *fpw = fopen(pathches[file_num - 1], “wb”);
i = 0;
for (; i < filesize % (file_num - 1); ++i) {
//边读编写
fputc(fgetc(fpr), fpw);
}
fclose(fpw);
}
fclose(fpr);
//释放
i = 0;
for (; i < file_num; ++i) {
free(pathches[i]);
}
free(pathches);
(*env)->ReleaseStringUTFChars(env, path_jstr, path);
(*env)->ReleaseStringUTFChars(env, path_pattern_jstr, path_pattern);
}
//合并
JNIEXPORT void JNICALL Java_cn_tsou_ndkfilecrypt_ndk_Cryptor_path
(JNIEnv *env, jclass jcls, jstring path_pattern_jstr, jint file_num, jstring total_jstr) {
//合并之后的文件
const char *merge_path = (*env)->GetStringUTFChars(env, total_jstr, NULL);
//分割指纹机的pattern
const char *path_pattern = (*env)->GetStringUTFChars(env, path_pattern_jstr, NULL);
//得到分割之后的子文件路径列表
char **pathches = malloc(sizeof(char *) * file_num);
int i = 0;
//不断读取path文件,循环写入file_num个文件中
for (; i < file_num; ++i) {
pathches[i] = malloc(sizeof(char) * 100);
//元素赋值
//需要分割的文件:C://jason/001.jpg
// 子文件:C://jason/001_%d.jpg
sprintf(pathches[i], path_pattern, (i + 1));
LOGI(“patch path:%s”, pathches[i]);
}
FILE *fpw = fopen(merge_path,“wb”);
//把所有的分割文件读取一遍,写入总的文件中
i=0;
for (; i < file_num; ++i) {
//每个子文件的大小
int filesize=get_file_size(pathches[i]);
FILE *fpr=fopen(pathches[i],“rb”);
int j=0;
for (; j <filesize ; ++j) {
fputc(fgetc(fpr),fpw);
}
fclose(fpr);
}
fclose(fpw);
//释放
i = 0;
for (; i < file_num; ++i) {
free(pathches[i]);
}
free(pathches);
(*env)->ReleaseStringUTFChars(env, total_jstr, merge_path);
(*env)->ReleaseStringUTFChars(env, path_pattern_jstr, path_pattern);
}
- 调用
import android.Manifest;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.Environment;
最后
说一千道一万,不如自己去行动。要想在移动互联网的下半场是自己占有一席之地,那就得从现在开始,从今天开始,马上严格要求自己,既重视业务实现能力,也重视基础和原理。基础夯实好了,高楼才能够平地而起,稳如泰山。
最后为了帮助大家深刻理解Android相关知识点的原理以及面试相关知识,这里放上相关的我搜集整理的24套腾讯、字节跳动、阿里、百度2020-2021面试真题解析,我把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包知识脉络 + 诸多细节。
还有 高级架构技术进阶脑图、Android开发面试专题资料 帮助大家学习提升进阶,也节省大家在网上搜索资料的时间来学习,也可以分享给身边好友一起学习。
点击:
《Android架构视频+BAT面试专题PDF+学习笔记》
即可免费获取~
理成了视频和PDF(实际上比预期多花了不少精力),包知识脉络 + 诸多细节。
还有 高级架构技术进阶脑图、Android开发面试专题资料 帮助大家学习提升进阶,也节省大家在网上搜索资料的时间来学习,也可以分享给身边好友一起学习。
[外链图片转存中…(img-0GxXYgsj-1646235535891)]
[外链图片转存中…(img-mkNMeYMn-1646235535893)]
[外链图片转存中…(img-W4rVY1kw-1646235535893)]
点击:
《Android架构视频+BAT面试专题PDF+学习笔记》
即可免费获取~
网上学习 Android的资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。希望这份系统化的技术体系对大家有一个方向参考。