NDK开发(二):文件的加密与解密&文件拆分和合并

//一次读取一个字符

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;

import android.support.annotation.NonNull;

import android.support.v4.app.ActivityCompat;

import android.support.v7.app.AppCompatActivity;

import android.util.Log;

import android.view.View;

import java.io.File;

import cn.tsou.ndkfilecrypt.ndk.Cryptor;

public class MainActivity extends AppCompatActivity {

String[] mPermissionList = new String[]{

Manifest.permission.WRITE_EXTERNAL_STORAGE,

Manifest.permission.READ_EXTERNAL_STORAGE};

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

}

@Override

public void onAttachedToWindow() {

super.onAttachedToWindow();

ActivityCompat.requestPermissions(MainActivity.this, mPermissionList, 100);

}

@Override

public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {

switch (requestCode) {

case 100:

boolean writeExternalStorage = grantResults[0] == PackageManager.PERMISSION_GRANTED;

boolean readExternalStorage = grantResults[1] == PackageManager.PERMISSION_GRANTED;

if (grantResults.length > 0 && writeExternalStorage && readExternalStorage) {

}

break;

}

}

/**

  • 加密

  • @param view

*/

public void mCrypt(View view) {

String normal_path = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separatorChar +

“huangxiaoguo” + File.separatorChar + “001.png”;

String crypt_path = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separatorChar +

“huangxiaoguo” + File.separatorChar + “crypt.png”;

try {

Cryptor.crypt(normal_path, crypt_path);

Log.e(“huangxiaoguo”, “加密完成”);

}catch (Throwable e){

Log.e(“huangxiaoguo”, “加密异常”);

e.printStackTrace();

}

}

/**

  • 解密

  • @param view

*/

public void mDecrypt(View view) {

String crypt = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separatorChar +

“huangxiaoguo” + File.separatorChar + “crypt.png”;

String decrypt_path = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separatorChar +

“huangxiaoguo” + File.separatorChar + “decrypt.png”;

Cryptor.decrypt(crypt, decrypt_path);

Log.e(“huangxiaoguo”, “解密完成”);

}

/**

  • 拆分

  • 整除:

  • 文件大小:90,分成9个文件,每个文件10

  • 不整除:

  • 文件大小:100,分成9个文件,

  • 前(9-1)个文件为(110/(9-1))=13

  • 最后一个文件(110%(9-1))=6

  • @param view

*/

public void mDiff(View view) {

String path = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separatorChar +

“huangxiaoguo” + File.separatorChar + “aaa.mp4”;

String path_pattern = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separatorChar +

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加V获取:vip204888 (备注Android)
img

题外话

我在一线互联网企业工作十余年里,指导过不少同行后辈。帮助很多人得到了学习和成长。

我意识到有很多经验和知识值得分享给大家,也可以通过我们的能力和经验解答大家在IT学习中的很多困惑,所以在工作繁忙的情况下还是坚持各种整理和分享。但苦于知识传播途径有限,很多程序员朋友无法获得正确的资料得到学习提升,故此将并将重要的Android进阶资料包括自定义view、性能优化、MVC与MVP与MVVM三大框架的区别、NDK技术、阿里面试题精编汇总、常见源码分析等学习资料。

【Android思维脑图(技能树)】

知识不体系?这里还有整理出来的Android进阶学习的思维脑图,给大家参考一个方向。

希望我能够用我的力量帮助更多迷茫、困惑的朋友们,帮助大家在IT道路上学习和发展~

一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
img
一线互联网企业工作十余年里,指导过不少同行后辈。帮助很多人得到了学习和成长。

我意识到有很多经验和知识值得分享给大家,也可以通过我们的能力和经验解答大家在IT学习中的很多困惑,所以在工作繁忙的情况下还是坚持各种整理和分享。但苦于知识传播途径有限,很多程序员朋友无法获得正确的资料得到学习提升,故此将并将重要的Android进阶资料包括自定义view、性能优化、MVC与MVP与MVVM三大框架的区别、NDK技术、阿里面试题精编汇总、常见源码分析等学习资料。

【Android思维脑图(技能树)】

知识不体系?这里还有整理出来的Android进阶学习的思维脑图,给大家参考一个方向。

[外链图片转存中…(img-mCTPti9f-1712803209156)]

希望我能够用我的力量帮助更多迷茫、困惑的朋友们,帮助大家在IT道路上学习和发展~

一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
[外链图片转存中…(img-sX5BZnsE-1712803209156)]

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值