Android 打包流程之aapt打包资源文件

article/2025/11/8 23:57:47

上一篇:Android打包流程之资源管理
Android应用最终是以apk的形式放在手机上安装并运行的,而负责将资源文件和代码进行打包的工具就叫appt,全称Android Asset Packaging Tool,翻译过来就是Android资源打包工具,是Android打包流程中不可或缺的一环。虽然build-tools中都会有一个aapt.exe负责打包apk,但底层还是通过执行aapt命令的方式来进行操作,所以这里需要了解一下aapt的相关命令,有助于更好的理解打包的流程。

Android打包流程简述

先来看张官方的打包流程图:


Android打包流程图

  1. 首先将资源文件(res目录下)通过aapt工具打包成R.java类(资源索引)和.arsc资源文件。
  2. 倘若工程中又aidl,则通过aidl工具将aidl打包成java接口类。
  3. R.java、aidl生成的java文件和项目中的源代码混合编译成.class文件
  4. class文件和第三方jar或者library通过dx工具打包成dex文件。dx工具的主要作用是将java字节码转换成Dalvik字节码,在此过程中会压缩常量池,消除一些冗余信息等。
  5. 通过apkbuilder工具将所有没有编译的资源,.arsc资源,.dex文件打包到一个完成apk文件中。
  6. 生成的apk通过Jarsinger工具,利用relese或debug下配置的keystore文件进行签名,得到签名后的apk文件。
  7. 通过zipAlign工具对签名后的apk进行对齐处理。即将APK包中所有的资源文件距离文件起始偏移为4字节整数倍,这样通过内存映射访问apk文件时的速度会更快。减少运行时内存的使用。

这就是Android打包成apk的流程,而资源的打包则涉及到许多aapt命令。

AAPT命令详解

1、aapt l[ist] [-v] [-a] file.{zip,jar,apk}
列出(zip、jar、apk)等类型压缩包中的所有文件列表,示例:

aapt list  app-debug.apk#list可以简写为l,如下:
aapt l  app-debug.apk

列出app-debug.apk中所有的文件列表:


在这里插入图片描述

打印出来的内容很长,在命令行中不方便观察,我们可以将输出的内容存放到.txt文件中便于查看。示例:

aapt list  app-debug.apk>a.txt

把输出的内容存入a.txt文件中。
aapt list后面还可以加-v和-a。例如加-v参数:

aapt list -v app-debug.apk>a.txt

也会列出apk中所有的文件列表,只不过更加详细:
在这里插入图片描述

其中各字段代表的含义如下:
Length:文件的长度。
Method:数据压缩算法,有Deflate和Stored两种。知道是用来压缩文件的就行。
Ratio:压缩率。
Size:文件压缩后节省的大小。跟压缩率有关。Size=(1-压缩率)*Length。
Date:日期。
Time:时间。
CRC-32:循环冗余校验,是一种加密算法。
Name:文件名称。

aapt list后面加-a参数:

aapt list -a app-debug.apk>a.txt

列出apk中所有的文件列表、资源id、各限定符下资源文件对应的id、AndroidManifest文件内容。


在这里插入图片描述

看下右边的滚动条,发现这个输出的内容不要太多,不要太详细。最底下列出了Android Manifest文件的内容。

2、aapt d[ump] [–values] [–include-meta-data] WHAT file.{apk} [asset [asset …]]
通过参数配置列出apk中各种详细信息,例如apk的权限、字符、资源等等。
主要有以下几种参数:

  1. strings
    列出apk中的所有字符资源(包括不同语言限定符):示例:
aapt dump strings app-debug.apk>a.txt

结果:


在这里插入图片描述

这里有乱码,有其它国家语言符号。大家可以自行试一试。

  1. badging
    Print the label and icon for the app declared in APK。实际内容不止label和icon。还有包名、versionCode、versionName、compileSdkVersion、targetSdkVersion等等信息,这里截取一小部分:


    在这里插入图片描述

  2. permissions
    列出apk所用到的所有权限。示例:

aapt dump permissions app-debug.apk

结果会列出apk所需要的所有权限,这里不贴图了。

  1. resources。
    输出apk中所有的资源信息,包括用户添加的资源、不同限定符下的系统资源等等,示例:
aapt dump resources app-debug.apk>a.txt

结果:


在这里插入图片描述

  1. configurations
    列出apk中所有的资源目录,注意,只是目录,不包含任何文件内容,资源目录对应不同的限定符。
aapt dump configurations app-debug.apk

关于限定符这篇文章有写到:限定符,结果如下:


在这里插入图片描述

5.xmltree
打印出指定xml文件的文档树结构。例如打印出项目中res/layout/activity_main.xml的树形结构,则可以这样写:

aapt d xmltree app-debug.apk res/layout/activity_main.xml

打印结果如下:


在这里插入图片描述

从上到下列出了activity_main.xml的文档树结构。

6.xmlstrings
列出给出的xml文件中所包含的控件名、控件的属性名和属性值等等。示例:

aapt d xmlstrings app-debug.apk res/layout/activity_main.xml

结果:


在这里插入图片描述

3、aapt p[ackage]
负责打包资源文件的命令,这个命令是aapt中最核心、最复杂的命令:

aapt p[ackage] [-d][-f][-m][-u][-v][-x][-z][-M AndroidManifest.xml] \[-0 extension [-0 extension ...]] [-g tolerance] [-j jarfile] \[--debug-mode] [--min-sdk-version VAL] [--target-sdk-version VAL] \[--app-version VAL] [--app-version-name TEXT] [--custom-package VAL] \[--rename-manifest-package PACKAGE] \[--rename-instrumentation-target-package PACKAGE] \[--utf16] [--auto-add-overlay] \[--max-res-version VAL] \[-I base-package [-I base-package ...]] \[-A asset-source-dir]  [-G class-list-file] [-P public-definitions-file] \[-D main-dex-class-list-file] \[-S resource-sources [-S resource-sources ...]] \[-F apk-file] [-J R-file-dir] \[--product product1,product2,...] \[-c CONFIGS] [--preferred-density DENSITY] \[--split CONFIGS [--split CONFIGS]] \[--feature-of package [--feature-after package]] \[raw-files-dir [raw-files-dir] ...] \[--output-text-symbols DIR]

好吧,来看下每个参数啥意义:

-d:包含一个或多个设备资源,由逗号分割。
-f:强制覆盖现有文件。
-m:生成包的目录在-j参数指定的目录。
-u:更新现有的包。
-v:详细输出,加上此命令会在控制台输出每一个资源文件信息,R.java生成后还有注释。
-x:创建拓展资源id。
-z:需要本地化的资源属性标记定位。
-M:指定AndroidManifest文件的路径。
-0:指定一个附加扩展名,对于该扩展名,此类文件将不会压缩存储在.apk中。空字符串表示不压缩所有文件。
-g:强制图片灰度,灰度值默认为0-jar:指定要包含的类的jar或zip文件。
--debug-mode:设置调试模式,即在AndroidManifest中加入  android:debuggable="true"
--min-sdk-version VAL:指定最小SDK版本 如是7以上 则默认编译资源的格式是 utf-8
--target-sdk-version VAL:AndroidManifest中指定目标编译版本sdk--app-version VAL:指定app的版本号。
--app-version-name TEXT:指定app的版本名。
--custom-package VAL:生成R.java到不同的包。
--rename-manifest-package PACKAGE:修改manifest中的应用包名。
--rename-instrumentation-target-package PACKAGE:重写指定包名的选项
--utf16:将资源的默认编码更改为UTF-16。在api在7或者更高时有用,资源的默认编码是utf-8--auto-add-overlay:自动添加资源覆盖。
--max-res-version VAL:最大资源版本,忽略高于给定值的版本化资源目录。
-I base-package:指定的SDK版本中android.jar的路径。
-A asset-source-dir:指定Assets文件夹路径。
-G class-list-file:指定用于输出混淆选项的文件。
-P public-definitions-file:指定的输出公共资源,可以指定一个文件 让资源ID输出到上面。
-D main-dex-class-list-file:指定主DEX的混淆选项输出的文件。
-S resource-sources:指定资源目录,一般是res。
-F apk-file:指定把资源输出到 apk文件中。
-J R-file-dir指定R.java的输出路径。
-c CONFIGS:指定资源有哪些限定符,中间以逗号分割,如en、port、land、en_US。
--preferred-density DENSITY:指定设备的屏幕密度,不符合此密度的资源将会被删除。
--split CONFIGS:分包构建apk,可以和主apk一起加载。
--output-text-symbols DIR:在指定的文件夹下生成一个包含R.java中的资源标识符的文本文件。

这命令复杂的分分钟让人抓狂-。-
但其实只要知道这个命令是做什么的就好,它就是用来将项目中的所有资源文件打包,经过我的实践,其最小执行单元如下:

aapt package -S [res文件夹路径] -M [AndroidManifest.xml文件路径] -I [sdk中android.jar的路径] -F [xxx.apk]

意思就是最起码要指定这四个值,才能执行aapt package命令。于是我这里执行了一个命令。

aapt package -S res -M E:\AndroidProjects\Dagger2\app\src\main\AndroidManifest.xml -I D:\Android\android-sdk-windows\platforms\android-28\android.jar -F out.apk

结果:


在这里插入图片描述

然后就报了这个错误,说是资源找不到,可用as打开工程,这些资源明明都能找到。一度陷入绝望,后来实在没办法,把这些资源删了,AndroidManifest.xml文件中删除这一行代码:android:theme="@style/TheTheme",于是才可以执行成功。至于加上这三个资源、指定主题为什么会报错,我在网上找了许多资料都没有找到这个问题的症结所在,若是有哪位大神知道这个问题的解决办法,还请在底下留言告诉我,不胜感激~我真的很想知道他喵的到底是为什么-。-

好了,至于打包后就是一个out.apk压缩文件,我们解压后,目录如下:
在这里插入图片描述

res文件夹里面是我们的资源目录:


在这里插入图片描述

至于resources.arsc就是资源打成的包了,将资源文件打包成.arsc的文件,就是我们上面流程图的第一步。以后打包apk的时候会将这个文件也一同打包进去。还有一个AndroidManifest.xml,打开后一堆看不懂的:
在这里插入图片描述

这里的文件内容做了处理,防止别人窥探到其中的代码。至于其它可以接的参数,这里只演示一个:

--rename-manifest-package PACKAGE:修改manifest中的应用包名。

好吧,然后我们在原来的命令上接入该参数:

aapt package -S res -M E:\AndroidProjects\Dagger2\app\src\main\AndroidManifest.xml -I D:\Android\android-sdk-windows\platforms\android-28\android.jar  -F out.apk --rename-manifest-package com.aapt.demo

在刚才命令的最后面加入–rename-manifest-package com.aapt.demo,把AndroidManifest.xml中的包名改成com.aapt.demo,打包完成后解压并查看AndroidManifest文件:


在这里插入图片描述

虽然大部分是乱码,可是我们还是能看到包名已经改成了com.aapt.demo。至于接其它的参数,笔者这里没有一个个试,其实常用的就那些,其他的都是辅助参数。

4、aapt r[emove] [-v] file.{zip,jar,apk} file1 [file2 …]
用于移除打包好的apk中的文件。例如移除打包好的apk中的AndroidManifest.xml文件:

aapt r out.apk AndroidManifest.xml

这里移除了out.apk中的AndroidManifest.xml文件,然后执行如下命令:

aapt d xmmtree out.apk AndroidManifest.xml

然后会出现如下错误:


在这里插入图片描述

提示该文件找不到,可见确实文件是被删除了。可是这里奇怪的是,解压apk,发现AndroidManifest.xml文件依旧在,但执行命令的时候就提示找不到。什么原因,暂时还不知道,有知道的可以告诉我。

5、 aapt a[dd] [-v] file.{zip,jar,apk} file1 [file2 …]
添加文件到打包好的apk中。示例:将a.txt、b.txt添加到打包好的apk中:

aapt a out.apk a.txt b.txt

多个文件中间以空格分割就好,然后看下解压apk,看其中的目录:


在这里插入图片描述

将a.txt和b.txt成功加入到apk中了。

6、 aapt c[runch] [-v] -S resource-sources … -C output-folder …
做PNG文件的预处理,并将结果存储到一个文件夹中。示例,把res目录下的图片预处理,并存储到任意路径pictures中:

aapt c -S res -C E:\AndroidProjects\Dagger2\app\src\main\pictures

执行后结果如下:


在这里插入图片描述

表示执行成功,然后我们看下pictures路径中的文件:


在这里插入图片描述

好吧,没什么可说的。

7、aapt s[ingleCrunch] [-v] -i input-file -o outputfile
对单个PNG文件进行预处理,并输出到指定文件:

aapt s -v -i[需要处理的图片文件路径] -o[处理完成后存储的图片文件路径]

示例:

aapt s -v -i E:\AndroidProjects\Dagger2\app\src\main\res\mipmap-hdpi\ic_launcher.png -o E:\AndroidProjects\Dagger2\app\src\main\pictures\a.png

这里预先在pictures文件夹中新建a.txt文件,然后把后缀名改成.png,这时候a.png是无法打开的,执行此命令后,a.png就可以打开了吗,显示的图像就是res中的hdpi目录下的ic_launcher.png。

8、 aapt v[ersion]
没什么好说的,显示aapt的版本


在这里插入图片描述

aapt的命令差不多就这么几种。在命令行中执行aapt命令,就可以查看aapt详细的用法。有兴趣的小伙伴可以自行试一试哈~

AAPT源码分析

关于源码,这里只是看一个脉络。需要下载Android系统源码并解压,下载地址:各版本系统源码下载。我这里下载的是6.0的源码。关于aapt部分的源码在frameworks\base\tools\aapt文件夹下。其入口在Main.cpp中main方法中。main方法共有近500行,这里只贴一部分来分析:

int main(int argc, char* const argv[])
{char *prog = argv[0];//Bundle对象用来存储输入的操作类型和相关的参数。Bundle bundle;bool wantUsage = false;int result = 1;    // pessimistically assume an error.int tolerance = 0;/* default to compression */bundle.setCompressionMethod(ZipEntry::kCompressDeflated);if (argc < 2) {wantUsage = true;goto bail;}....//argv[] 一行aapt命令被分割成字符串数组。//这边判断该数组的第二个元素的第1个字符,如aapt package,argv[1][0]获取到的就是p。else if (argv[1][0] == 'p')//设置执行类型为打包。bundle.setCommand(kCommandPackage);....argc -= 2;argv += 2;/** Pull out flags.  We support "-fv" and "-f -v".*/while (argc && argv[0][0] == '-') {/* flag(s) found */const char* cp = argv[0] +1;while (*cp != '\0') {switch (*cp) {......//收集appt命令输入的参数,这些参数以"-"开头。case '-':if (strcmp(cp, "-debug-mode") == 0) {//例如这里就获取到了-debug-mode,然后设置Bundle的debugMode为true。bundle.setDebugMode(true);} .....cp += strlen(cp) - 1;break;default:fprintf(stderr, "ERROR: Unknown flag '-%c'\n", *cp);wantUsage = true;goto bail;}cp++;}argc--;argv++;}/** We're past the flags.  The rest all goes straight in.*/bundle.setFileSpec(argv, argc);//执行最终的命令,并得到结果result = handleCommand(&bundle);bail:if (wantUsage) {usage();result = 2;}//printf("--> returning %d\n", result);return result;
}

源码中比较详细,这里举个例子。整行aapt命令会被分割成字符串数组。然后去字符串数组的第二个的第一个字符,如aapt package…,得到p,代表这是aapt打包命令。Bundle对象用以存储输入的操作类型和相关的参数,供后面执行命令详细操作时使用。当然,命令解析错误时,会通过goto跳转到bail代码块,比如:

 default:fprintf(stderr, "ERROR: Unknown flag '-%c'\n", *cp);wantUsage = true;goto bail;

bail代码块:

bail:if (wantUsage) {usage();result = 2;}//printf("--> returning %d\n", result);return result;
}

好吧,会调用usage()函数,这个函数会打印出aapt的用法文档。

void usage(void)
{fprintf(stderr, "Android Asset Packaging Tool\n\n");fprintf(stderr, "Usage:\n");fprintf(stderr," %s l[ist] [-v] [-a] file.{zip,jar,apk}\n""   List contents of Zip-compatible archive.\n\n", gProgName);fprintf(stderr," %s d[ump] [--values] [--include-meta-data] WHAT file.{apk} [asset [asset ...]]\n""   strings          Print the contents of the resource table string pool in the APK.\n""   badging          Print the label and icon for the app declared in APK.\n""   permissions      Print the permissions from the APK.\n""   resources        Print the resource table from the APK.\n""   configurations   Print the configurations in the APK.\n""   xmltree          Print the compiled xmls in the given assets.\n""   xmlstrings       Print the strings of the given compiled xml assets.\n\n", gProgName);fprintf(stderr," %s p[ackage] [-d][-f][-m][-u][-v][-x][-z][-M AndroidManifest.xml] \\\n""        [-0 extension [-0 extension ...]] [-g tolerance] [-j jarfile] \\\n""        [--debug-mode] [--min-sdk-version VAL] [--target-sdk-version VAL] \\\n""        [--app-version VAL] [--app-version-name TEXT] [--custom-package VAL] \\\n""        [--rename-manifest-package PACKAGE] \\\n""        [--rename-instrumentation-target-package PACKAGE] \\\n""        [--utf16] [--auto-add-overlay] \\\n""        [--max-res-version VAL] \\\n""        [-I base-package [-I base-package ...]] \\\n""        [-A asset-source-dir]  [-G class-list-file] [-P public-definitions-file] \\\n""        [-S resource-sources [-S resource-sources ...]] \\\n""        [-F apk-file] [-J R-file-dir] \\\n""        [--product product1,product2,...] \\\n""        [-c CONFIGS] [--preferred-density DENSITY] \\\n""        [--split CONFIGS [--split CONFIGS]] \\\n""        [--feature-of package [--feature-after package]] \\\n""        [raw-files-dir [raw-files-dir] ...] \\\n""        [--output-text-symbols DIR]\n"

这是代码,看下我们执行aapt时的输出:


在这里插入图片描述

是不是就是这个?好吧,当命令校验成功,会执行handleCommand方法,并传入一个Bundle对象。看下handleCommand方法的代码:

/** Dispatch the command.*/
int handleCommand(Bundle* bundle)
{//printf("--- command %d (verbose=%d force=%d):\n",//    bundle->getCommand(), bundle->getVerbose(), bundle->getForce());//for (int i = 0; i < bundle->getFileSpecCount(); i++)//    printf("  %d: '%s'\n", i, bundle->getFileSpecEntry(i));switch (bundle->getCommand()) {case kCommandVersion:      return doVersion(bundle);case kCommandList:         return doList(bundle);case kCommandDump:         return doDump(bundle);case kCommandAdd:          return doAdd(bundle);case kCommandRemove:       return doRemove(bundle);case kCommandPackage:      return doPackage(bundle);case kCommandCrunch:       return doCrunch(bundle);case kCommandSingleCrunch: return doSingleCrunch(bundle);case kCommandDaemon:       return runInDaemonMode(bundle);default:fprintf(stderr, "%s: requested command not yet supported\n", gProgName);return 1;}
}

也没什么,就判断是哪种命令,比如package、dump、add、remove,然后再去做具体的操作,如doPackage、doDump、doRemove等等。不过这些方法是通过外部引用的,其真正的代码在同目录下的Command.cpp文件中,这个c文件实现了所有的aapt命令的具体代码。这里举一个稍微简单的例子doRemove看一下:

/** Delete files from an existing archive.*/
int doRemove(Bundle* bundle)
{//命令行举例:aapt r out.apk AndroidManifest.xmlZipFile* zip = NULL;status_t result = UNKNOWN_ERROR;const char* zipFileName;if (bundle->getFileSpecCount() < 1) {//如果没有指定压缩包名称,提示必须指定压缩包名称fprintf(stderr, "ERROR: must specify zip file name\n");goto bail;}//获取到压缩文件名称。[out.apk,AndroidManifest.xml]数组中的第一个。zipFileName = bundle->getFileSpecEntry(0);//[out.apk,AndroidManifest.xml]数组大小小于2,说明没有要移除的文件。if (bundle->getFileSpecCount() < 2) {fprintf(stderr, "NOTE: nothing to do\n");goto bail;}//类似于java中的打开输入输出流。zip = openReadWrite(zipFileName, false);if (zip == NULL) {//打开文件失败。fprintf(stderr, "ERROR: failed opening Zip archive '%s'\n",zipFileName);goto bail;}//索引从1开始,可以有多个要删除的文件。for (int i = 1; i < bundle->getFileSpecCount(); i++) {//获取要删除的文件名。const char* fileName = bundle->getFileSpecEntry(i);ZipEntry* entry;//获取要删除的文件。entry = zip->getEntryByName(fileName);if (entry == NULL) {//文件找不到printf(" '%s' NOT FOUND\n", fileName);continue;}//找到该文件则删除该文件。result = zip->remove(entry);if (result != NO_ERROR) {fprintf(stderr, "Unable to delete '%s' from '%s'\n",bundle->getFileSpecEntry(i), zipFileName);goto bail;}}//相当于java中输入输出流的刷新。zip->flush();bail:delete zip;return (result != NO_ERROR);
}

首先会判断命令中有没有指定压缩包,如果没有,会报错。有指定压缩包才会去获取命令中压缩包的名称。如果没有指定要删除的文件,会提示没有指定要删除的文件。否则打开文件,在打开文件成功的情况下,循环遍历要删除的文件,依次把该文件从压缩包中删除,全部操作完成后刷新压缩包中的内容。

以上就是执行aapt remove命令底层所执行的详细代码了,说到底aapt所有的命令最底层都是在操作文件。只是google把这些复杂的文件操作封装成命令工具供我们使用。这里的源码分析也只是看一个大体的结构,更具体的实现,各位小伙伴有兴趣可以去翻一翻源码啊,不一定要精通c++,有一点基础或者其它语言基础也能看得懂大概的流程,除非涉及到修改然后重新编译成定制化的aapt命令,那又是另外一回事了。

好了,关于aapt命令就写到这里了,知道怎么用,底层大概是怎么实现的就可以了,有深厚c++功底的同学可以自己尝试改一改。文章中若是有不足或错误,看到的小伙伴可以在底下留言告诉我,小菜鸟不胜感激~


http://chatgpt.dhexx.cn/article/GPgvnE7N.shtml

相关文章

Android文件格式

在Android的priv-app目录下发现有oat类型的文件夹 什么是oat&#xff1f; It’s Of Ahead Time, a silly reordering of Ahead Of Time. We went with that because then we say that process of converting .dex files to .oat files would be called quakerizing and that wo…

Android项目打包生成apk文件

Android开发打包生成APK文件 打包apk文件分为两种 无需密钥的apk有密钥的apk(常规) 他们的区别只是就是安全问题。 1.没有密钥的apk 点击之后会自动生成没有密钥的APK。 在编辑器的右下角会出现该弹窗&#xff0c;点击location会帮你找到该文件 2.有密钥的APK 1.找到bui…

Java利用mpxj解析mpp格式文件

转载请注明来源&#xff1a;http://blog.csdn.net/loongshawn/article/details/51038051 《Java利用mpxj解析mpp格式文件》《SpringBoot添加Email发送功能》《SpringBoot配置log4j输出日志》《SpringBoot定时任务说明》《SpringBoot接口服务处理Whitelabel Error Page》《构建…

java解析mpp文件(包含层级关系)

我用的是递归循环的&#xff0c;不限制有多少子级关系都可以拿到 首先引入解析mpp所需依赖 <dependency><groupId>net.sf.mpxj</groupId><artifactId>mpxj</artifactId><version>7.1.0</version></dependency>解析所用实体类…

Date转换年月日

timebasic.js //时间戳转年月日 export function format(shijianchuo) {//shijianchuo是整数&#xff0c;否则要parseInt转换var time new Date(shijianchuo);var y time.getFullYear();var m time.getMonth() 1;m m < 10 ? "0" m : m;var d time.getDate…

C# 接口中DateTime类型字段返回年月日格式,去掉时分秒的数据

背景 在我们平时写接口的时候&#xff0c;避免不了这样一个问题&#xff0c;数据库中存的字段类型为datetime,代码中对应的实体类也是DateTime类型的字段&#xff0c;于是在读取数据库内容之后返回的数据也是DateTime类型的值&#xff0c;比如2022-10-24 18:34:56.110&#xf…

vue3-用dayjs将时间戳转为年月日格式

已知&#xff0c;格式化时间&#xff1a;dayjs(cellValue).format(YYYY-MM-DD) 用法&#xff1a; import dayjs from dayjs;dayjs(时间戳).format(YYYY-MM-DD HH:mm:ss); 如&#xff0c;在get请求中使用&#xff1a; service.get(/trace/sourceSearchInput.value).then(res …

Java但中获取时间将时间转换成字符串格式(年月日格式)

一:直接上马拿走&#xff1a; package cn.wyj.one;import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date;/*** 测试时间对象和字符串之间的相互转化* DateFormat抽象类和SimpleDateFormat实现类的使用* author 86155**/public class Demo2…

Excel修改日期格式:日月年-年月日

最近处理数据&#xff0c;遇到需要处理一下日期格式&#xff0c;记一下。。。 1、原格式 2、新建Excel表&#xff0c;复制到表中&#xff0c;选择列&#xff0c;数据-分列&#xff0c;下一步…,选择列格式为“DMY”,点击完成 3、效果(若不成功&#xff0c;可以试一试其他的)

各种加密证书

证书相关知识 PFX文件属于数字证书。pfx数字证书既包含有公钥又包含私钥&#xff0c;cer | crt数字证书只包含公钥。参考 JKS&#xff08;Java Key Store&#xff09;就是利用Java Keytool 工具生成的Keystore文件&#xff0c;JKS文件由公钥和密钥构成&#xff0c;其中的公钥…

公钥,私钥,数字签名,证书

今天&#xff0c;我读到一篇好文章。 它用图片通俗易懂地解释了&#xff0c;"数字签名"&#xff08;digital signature&#xff09;和"数字证书"&#xff08;digital certificate&#xff09;到底是什么。 我对这些问题的理解&#xff0c;一直是模模糊糊…

国密SSL证书保障网站安全

国内很多网站为了网站安全都会部署SSL证书&#xff0c;目前市面上申请到的SSL服务器证书基本都是采用RSA国际算法&#xff0c;市场上80%的SSL服务器证书都是由国外CA尤其是美国为主的CA签发的证书。 网络安全就是国家安全&#xff0c;网络安全的对手也已经不仅仅是黑客&#xf…

构建用于签名/加密双证书测试体系的可执行命令

注意事项 生成证书请求的填写 范例Subject: C CN, ST Beijing, L Beijing, O MSI, OU msi, CN ca, emailAddress cagmssl.com 前面的步骤存在错误&#xff0c;后面改用脚本进行证书生成&#xff0c;阅读时请跳过前面错误的内容 错误的内容 -> 开始 CA 生成私钥 o…

来此加密证书申请,验证,自动部署

之前用certbot, 后来一直不报错, 证书不管用, 就想着干脆直接使用来此加密, 不要中间商了, 就有了直接到来此加密注册之旅 注册地址: 来此加密https://letsencrypt.osfipin.com/user-0408/order/list附上这两年的"战绩" 申请这么多证书主要原因是, 测试域名太多, 一…

加密和数字证书

目录 一 KPI概述二 KPI应用1 内容安全加密2 加密文件3 使用非对称加密对称加密密钥4 非对称加密的缺点5 数字签名6 数字证书7 时钟服务8 私钥使用者认证9 总结附&#xff1a;U盾的工作原理介绍 三 详解公钥、私钥、数字证书的概念1 加密和认证2 公钥和私钥3 证书4 总结5 签名证…

加密解密和CA证书杂记

最近两三个月&#xff0c;断断续续的一直在处理CA证书相关的事情。CA证书本质上也是一种加解密&#xff0c;因此就自然而然的涉及到一些加密和解密的技术&#xff0c;这就让我在了解CA的同时&#xff0c;也对加密和解密有了更进一步的认识和理解。 以下便是一个比较杂&#xff…

证书和加解密

刚进公司&#xff0c;在实习期需要了解很多关于加解密算法和证书相关的东西&#xff0c;我以写博客的方式把我近1个多月了解的东西整理出来传授给大家&#xff0c;大家觉得可以的话请不要吝啬你们的赞。 目录 什么是PKI 证书申请流程 加密与解密 签名认证 数字信封 数字…

HTTPS(对称加密+非对称加密+证书)

目录 1. 加密和解密 HTTPS工作过程 2. 对称加密 3. 对称加密 4. 既然都有非对称加密了,那为啥还要有对称加密 5. 中间人攻击 6. 引入证书 HTTPS 也是一个应用层协议. 是在 HTTP 协议的基础上引入了一个加密层. HTTP 协议内容都是按照文本的方式明文传输的. 这就导致在…

非对称加密与数字证书

文章目录 1 非对称加密2 数字签名3 数字证书4 数字签名和数字证书的区别5 CA 认证中心如何保证权威性6 HTTPS 协议7 HTTPS 与 SSL8 为什么不一直使用HTTPS 1 非对称加密 非对称加密&#xff0c;是指不能从加密密钥推算出解密密钥。加密密钥不需要保密&#xff0c;可以公开&…

安全和加密CA证书

一、介绍 1、为什么要加密 ※ 不加密流量的易受攻击性 ● 密码/数据嗅探 ● 数据操作 ● 验证操作 ● 相当于邮寄明信片 ※ 不安全的传统协议 --明文 ● telnet、FTP、POP3等等&#xff1b;不安全密码 ● http.smtp、…