CTF-Bugku逆向题Android方法归纳

1.signin题目:

reverse()

功能:反转数组里的元素的顺序
语法:arrayobject.reverse.()
这类方法会改变原来的数组,不可逆转

tostring()

功能:将各类进制的数字转化为字符串
语法:number.toString(radix)(radix代表进制数)
字符串的管理地方是string.xml
java在引用函数时要倒着引用

StringBuffer

当对字符串进行修改的时候,需要使用 StringBuffer 和 StringBuilder 类。
和 String 类不同的是,StringBuffer 和 StringBuilder 类的对象能够被多次的修改,并且不产生新的未使用对象。
在使用 StringBuffer 类时,每次都会对 StringBuffer 对象本身进行操作,而不是生成新的对象,所以如果需要对字符串进行修改推荐使用 StringBuffer。
StringBuilder 类在 Java 5 里被提出,它和 StringBuffer 之间的最大不同在于 StringBuilder 的方法不是线程安全的(不能同步访问)。
由于 StringBuilder 相较于 StringBuffer 有速度优势,所以多数情况下建议使用 StringBuilder 类。
在这里插入图片描述

Toast:

Android里的Toast是一类简易的消息提示框。Toast是包含用户点击消息。Toast类会帮助你创建和显示这些。
当视图显示给用户,在应用程序里显示为浮动。
Toast类的思想就是尽可能不引人注意,同时还向用户显示信息,希望他们看到。而且Toast显示的时间有限,Toast会根据用户设置的显示时间后自动消失。
Toast 最常见的创建方式是使用静态方法 Toast.makeText。
例如:
Toast.makeText(MainActivity.this, text “”, Toast.LENGTH_SHORT).show();
分析:
Toast是为了提醒用户,而又不影响用户的操作的提示栏。
方法里的MainActivity.this表示在MainActivity这个文件里显示;
text在后面的引号里输入想输出的文本。
text可以替换为R.string.自己定义的文本,表示引用string下的文本的资源;
LENGTH_SHORT表示Toast的显示时间一微秒计算,这里调用系统定义好的时间,也可自己写入确定的时间。
.show(); 是用来将定义好的Toast显示在MainActivity里的,如果不调用.show();方法定义的Toast就没有任何意义。

getBaseContext()

getBaseContext() 返回由构造函数指定或setBaseContext()设置的上下文
可以使用getContext()获取视图对象的上下文。 如果要创建一个只要存在活动就存在的新对象,则使用活动上下文或this,否则,活动将不会被破坏并最后导致内存泄漏。 如果需要与应用程序的全局生命周期相关联的上下文,并且应该在需要创建当前活动之外存在的对象的任何地方使用上下文,则可以使用getApplicationContext()。
View.getContext():返回视图当前运行的上下文。通常是当前活跃的活动。
Activity.getApplicationContext():返回整个应用程序的上下文(所有活动都在其内部运行的进程)。如果您需要一个与整个应用程序的生命周期相关联的上下文,而不仅仅是当前的活动,请使用它而不是当前的活动上下文。
ContextWrapper.getBaseContext()如果需要从另一个上下文里访问上下文,则采纳
ContextWrapper。从ContextWrapper内部引用的上下文通过getBaseContext()访问。

getString

getString表示以 Java 编程语言里String的形式获取此 ResultSet对象的当前行里指定列的值。

onCreate()

对onCreate()方法用super.onCreate()方法的理解,
首先要知道super.onCreate()方法的作用,就是用父类的onCreate方法记住当前活动的镜像,当下次再执行到这个活动的时候还是从这个镜像开始执行
但是此处需用super,因为这是调用父类的方法,为什么不能用this,是因为在子类里有一个和父类同名的方法就是onCreate,如果用this,就是用本类的实例来调用onCreate,而它偏偏又写在了onCreate里,这就形成了递归调用,所以一定要用super

如果写在你自己定义的一个OnCreate(),在这个函数里写调用OnCreate的话,需要写super.OnCreate(),否则会递归调用,
其他地方写的话,super是调用父类的,this是调用你覆盖的,不过一般没有人会去手动调用这玩意吧,因此一般是调用super.OnCreate().
首先我们可以看到, HelloWorldActivity 是继承自 Activity 的。 Activity 是 Android 系统提供的一个活动基类, 我们项目里所有的活动都需要继承它才能拥有活动的特性。 然后可以 看到HelloWorldActivity里有两个方法, onCreateOptionsMenu()这个方法是用于创建菜单的, 我们可以先无视它, 主要看下 onCreate()方法。 onCreate()方法是一个活动被创建时要执行的方法, 其里只有两行代码, 并且没有 Hello world!的字样。那么图 1.15里显示的 Hello world! 是在哪里定义的呢? 其实 Android程序的设计讲究逻辑和视图分离, 因此是不推荐在活动里直接编写界面的, 更加通用的一类做法是, 在布局文件里编写界面,然后在活动里引入进来。你可以看到,在 onCreate()方法的第二行调用了 setContentView()方法,就是这个方法给当前的活动引入了一 个 hello_world_layout 布局,那 Hello world!一定就是在这里定义的了!

setContentView()

在Acitivty里setContentView()用来设置布局文件

findViewById()

findViewById()是找xml布局文件下的具体widget控件(如Button、TextView等)。

setOnClickListener监听

Android onClick 与 setOnClickListener区别
为Android Widgets添加点击事件处理函数有两类方法,一个是在Xml文件里添加onClick属性,然后在代码里添加对应的函数。另一个是直接在代码里添加setOnClickListener函数。两者什么区别呢?
者的共同点
两者底层没有区别。
两者的区别
使用第一类方法的注意事项:

  1. 事件处理函数为public的。
  2. 事件处理函数在Activity里定义。
  3. 事件处理函数需有一个View类型的参数。

getText()

getText()为返回数据窗口控件里悬浮在当前行列之上的编辑框里的文本。

Timer题目:

JEB相当于Windows平台上的IDA
smali代码:双击Bytecode,出现smali代码;相较于C之汇编,那么smali之于Java

onCreate:

一个activity启动回调的第一个函数就是onCreate,这个函数主要做这个activity启动的一些需要的初始操作的工作。
onCreate之后调用了还有onRestart()和onStart()等。

System.loadLibrary:

System.load 和 System.loadLibrary详解
1.它们都可以用来装载库文件,不论是JNI库文件还是非JNI库文件。在任何本地方法被调用之前需先用这个两个方法之一把相应的JNI库文件装载。
2.System.load 参数为库文件的绝对路径,可以是任意路径。
例如你可以这样载入一个windows平台下JNI库文件:
System.load(“C://Documents and Settings//TestJNI.dll”);。
3. System.loadLibrary 参数为库文件名,不包含库文件的扩展名。
例如你可以这样载入一个windows平台下JNI库文件
System. loadLibrary (“TestJNI”);
System.loadLibrary(“lhm”); // 它的作用即是把我们在Java code里声明的native方法的那个libraryload进来,或者load其他什么动态连接库

System.currentTimeMillis():

功能:产生一个当前的毫秒,这个毫秒事实上就是自1970年1月1日0时起的毫秒数,Date()事实上就是相当于Date(System.currentTimeMillis());
由于Date类还有构造Date(long date),用来计算long秒与1970年1月1日之间的毫秒差。
得到了这个毫秒数。利用函数Calendar的出的结果就是年月日分秒。
System.currentTimeMillis()
获得的是自1970-1-01 00:00:00.000 到当前时刻的时间距离,类型为long

View:

View是所有Android里所有控件的基类,是界面层次上的一类抽象
在这里插入图片描述
不管是简单的TextView,Button还是复杂的LinearLayout和ListView,它们的共同基类都是View;
View是一类界面层的控件的一类抽象,它代表了一个控件,除了View还有ViewGroup,从名字来看ViewGroup可以翻译为控件组,即一组View;
在Android里,ViewGroup也继承了View,这就意味着View可以是单个控件,也可以是由多个控件组成的一组控件;

Handler:

现在作为客户,有这样一个需求,当打开Activity界面时,开始倒计时,倒计时结束后跳转新的界面(类同于各个APP的欢迎闪屏页面)。
作为初学者,可能觉得直接开启一个包含倒序循环的子线程就ok了
逻辑很简单,但当点进入界面时,会发现程序奔溃了。
由此我们发现在安卓开发里,例如上面的示例,我们常常通过一个线程来完成某些操作,然后同步显示对应的视图控件UI上,安卓里无法直接通过子线程来进行UI更新操作,对于这类情况,Android提供了一套异步消息处理机制Handler。

从开发角度角度来说,Handler是Android消息机制的上层接口,通过handler,可以将一个任务切换到handler所在的线程里执行,我们通常使用handler来更新UI,但更新UI仅仅是的使用场景之一,handler并不是仅仅用来更新UI。

更新UI的具体情况是这样的:和其他GUI库一样,Android的UI也是线程不安全的,也就是说想要更新应用程序里的UI元素,则需要在主线程里进行。所以主线程又叫做UI线程。若在子线程里更新UI程序会报CalledFromWrongThreadException错误。但是我们经常有这样一类需求:需要在子线程里完成一些耗时任务后根据任务执行结果来更新相应的UI。这就需要子线程在执行完耗时任务后向主线程发送消息,主线程来更新UI。

简单来说,Handler就是用来传递消息的。
Handler可以当成子线程与主线程的消息传送的纽带。在安卓开发里,在子线程里无法刷新UI,是因为UI在子线程里刷新的话,是不安全的,就比如多个线程刷新UI,会造成UI更新冲突,这样是不安全的。
所以,Handler的作用就来了,子线程可以通过Handler来将UI更新操作切换到主线程里执行。

postDelayed:

这是一类可以创建多线程消息的函数
使用方法:
1,首先创建一个Handler对象
Handler handler=new Handler();
2,然后创建一个Runnable对象
Runnable runnable=new Runnable(){
@Override
public void run() {
// TODO Auto-generated method stub
//要做的事情,这里再次调用此Runnable对象,以实现每两秒实现一次的定时器操作
handler.postDelayed(this, 2000);
}
};
3,使用PostDelayed方法,两秒后调用此Runnable对象
handler.postDelayed(runnable, 2000);
实际上也就实现了一个2s的一个定时器
4,如果想要关闭此定时器,可以这样操作
handler.removeCallbacks(runnable);
只要更改延时的时间就可以实现了,用一个static对象的话会比较容易操作。
是可以异步效果,但Runnable的执行是在Handler对象所在的线程
如果其所在的线程是UI线程的话,Runnable里还是不能执行耗时操作,不然会ANR
在这里插入图片描述

Native层:

分层方式里,Native层就是本地框架。
android native层是 相对于Java 层的底层,一般用c++开发
Java框架层就是常说的Framework,这层里东西很多也很复杂,比如说主要的一些系统服务如ActivityManagerService、PackageManagerService等,我们编写的Android代码之所以能够正常识别和动作,都要依赖这一层的支持。这一层也是由Java语言实现。
Native层这部分常见一些本地服务和一些链接库等。这一层的一个特点就是通过C和C++语言实现。比如我们现在要执行一个复杂运算,如果通过java代码去实现,那么效率会非常低,此时可以选择通过C或C++代码去实现,然后和我们上层的Java代码通信(这部分在android里称为jni机制)。又比如我们的设备需要运行,那么必然要和底层的硬件驱动交互,也要通过Native层。

JNI是Java Native Interface(Java本地接口)的缩写,JNI不是Android专有,而是从Java继承而来。Android作为一类嵌入式操作系统,大量个驱动、硬件相关的功能底层功能都必须在native层实现,JNI的作用和重要性大大增强。

stringFromJNI2:

Native层一个底层的函数

onCreateOptionsMenu():
Android一共有三类形式的菜单:
1.选项菜单(optinosMenu)
2.上下文菜单(ContextMenu)
3.子菜单(subMenu)
其里最常用的就是选项菜单(optionsMenu), 该菜单在点击 menu 按键 后会在对应的Activity底部显示出来。
public boolean onCreateOptionsMenu(Menu menu) {
/**

  • 此方法用于初始操作菜单,其里menu参数就是即将要显示的Menu实例。 返回true则显示该menu,false 则不显示;
  • (只会在第一次初始操作菜单时调用) Inflate the menu; this adds items to the action bar
  • if it is present.
    */
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
    }

1.Activity菜单机制 (与dialog类似)
Activity有一套机制来实现对菜单的管理,方法如下:
   1.public boolean onCreateOptionsMenu(Menu menu)
此方法用于初始操作菜单,其里menu参数就是即将要显示的Menu实例。
返回true则显示该menu,false 则不显示;
(只会在第一次初始操作菜单时调用)

2.public boolean onPrepareOptionsMenu(Menu menu)
在onCreateOptionsMenu执行后,菜单被显示前调用;如果菜单已经被创建,则在菜单显示前被调用。
同样的, 返回true则显示该menu,false 则不显示;
(可以通过此方法动态的改变菜单的状态,比如加载不同的菜单等)

3.public void onOptionsMenuClosed(Menu menu)
每次菜单被关闭时调用.
(菜单被关闭有三类情形,menu按钮被再次点击、back按钮被点击或者用户选择了某一个菜单项)

3+.public boolean onOptionsItemSelected(MenuItem item)
菜单项被点击时调用,也就是菜单项的监听方法。
通过这几个方法,可以得知,对于Activity,同一时间只能显示和监听一个Menu 对象。

getMenuInflater():

MenuInflater是用来解析定义在menu 目录下的菜单布局文件的,类似于LayoutInflater 是用来解析定义在layout 下的布局文件。传统意义上的定义菜单感觉比较繁琐,使用
MenuInflater 生成菜单会非常清晰简单。
我们知道,LayoutInflater是用来实例操作整个布局文件,而 MenuInflater是用来实例操作Menu目录下的Menu布局文件的。
传统意义上的菜单定义需要Override Activity的onCreateOptionsMenu,然后在里面调用Menu.add把Menu的一个个item加进来,比较复杂。而通过使用MenuInflater可以把Menu的构造直接放在Menu布局文件里,真正实现模型(Model)与视图(View)的分离,程序也看着清爽多了。
与LayoutInflater相比,MenuInflater的用法简单多了。首先,MenuInflater获取方法只有一类:Activity.getMenuInflater();其次,MenuInflater.inflater(int menuRes,Menu menu)(这里不代表inflater就是static方法,可以这样调用,只是为了描述方便)的返回值是void型,这就决定了MenuInflater.inflater后就没有后续操作了。这说明通过这类方式把Menu布局文件写好后就不能在程序里动态修改了,而不像LayoutInflater.inflater那样,返回值是View型,可以进行后续的进一步操作。另外,MenuInflater只有一个void inflater(int menuRes,Menu menu)非构造方法。

inflate():

inflate是用来把XML定义好的布局找出来,inflate之后并没有直接显示,需要再加入到其他布局里才能显示,以下是inflate的三类使用方法.
使用LayoutInflater.inflater方法
使用context.getSystemService方法
使用View.inflate方法

Inflate()作用就是将xml定义的一个布局找出来,但仅仅是找出来而且隐藏的,没有找到的同时并显示功能。
android上还有一个与Inflate()类同功能的方法叫findViewById(),二者有时均可使用,但也有区别
区别在于:
如果你的Activity里用到别的layout,比如对话框layout,你还要设置这个layout上的其他组件的内容,你就需以inflate()方法先将对话框的layout找出来,然后再用findViewById()找到它上面的其它组件。例如:
View view1=View.inflate(this,R.layout.dialog_layout,null);
  TextViewdialogTV=(TextView)view1.findViewById(R.id.dialog_tv);
  dialogTV.setText(“abcd”);
注:R.id.dialog_tv是在对话框layout上的组件,而这时若直接
用 this.findViewById(R.id.dialog_tv)肯定会报错。
View viewStub = ((ViewStub) findViewById(R.id.stubView)).inflate();

Inflate()或可理解为“隐性膨胀”,隐性摆放在view里,inflate()前只是获得控件,但没有大小没有在View里占据空间,inflate()后有一定大小,只是出于隐藏状态

onOptionsItemSelected():

public boolean onOptionsItemSelected(MenuItem item)
菜单项被点击时调用,也就是菜单项的监听方法。
只要菜单里的菜单项被点击,都会触发onOptionsItemSelected(MenuItem item)
item参数即为被点击的菜单项,那么需要在此方法内判断哪个Item被点击了,从而实现不同的操作。
//当客户点击MENU按钮的时候,调用该方法
@Override
public boolean onCreateOptionsMenu(Menu menu) {
menu.add(0, 1, 1, R.string.exit);
menu.add(0,2,2,R.string.about);
return super.onCreateOptionsMenu(menu);
}
//当客户点击菜单里的某一个选项时,会调用该方法
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if(item.getItemId() == 1){
finish();
}
return super.onOptionsItemSelected(item);
}

getItemId:

它返回的是该postion对应item的id

Mobile1题目:

java.security.MessageDigest类

功能:用于为应用程序提供信息摘要算法的功能,如md5和SHA。换句话说,就是生成md5或者是SHA密码。
相关:
getinstance:静态函数,用来实例操作和初始操作。
update:处理数据,更新摘要
reset:重置摘要
digest:明文变为密文

getBytes():

在Java里,String的getBytes()方法是得到一个操作系统默认的编码格式的字节数组。
Android系统下的String.getBytes()和new String()
Android属于LINUX系统,String是以UTF-8形式存储的,因此默认的String.getBytes()是长度为3的数组,二通常WIN的String是以GBK形式存储的。若不转换,就可能出现乱码
不同于getByte(),getByte()返回字符的ascii码值
str.getBytes(UTF-8); 的意思是以UTF-8的编码取得字节
Public class Test{
Public static void main(String args[]){
String str1 = new String(“runoob”);
Byte[] str2 = str1.getBytes();
System.out.println(str2);

str2 = str1.getBytes(“UTF-8”);
System.out.println(str2);
}
}
结果:
B@7852e922
B@4e25154f

toHexString():

Integer.toHexString():此方法返回的字符串表示的无符号整数参数所表示的值以十六进制(基数为16)。
在加密代码里,经常看到类同Integer.toHexString(b[i] & 0xFF)这样的代码,那么这行代码到底是什么意思呢(b是一个byte[])?为什么要&0xFF呢?
这句代码的最后目的是把byte[]转换为16进制字符串
toHexString()是把一个int转换为十六进制String
& 0xFF是为了保证byte类型转int后其二进制的一致,即补零扩展。那么为什么要补零扩展呢?因为我们是要把每一个byte类型的数据都转换位16进制字符串,补零扩展的话就可以忽略前24位
对于正数,byte可以直接转int,但是当byte类型的数是负数时,就比较特殊了。
int是32位,byte是8位,所以需要补位
负数在java里是以补码表示
byte是一个字节,最高位为符号位,则范围为[10000000,01111111],即[-128,127],注意此处范围边界值10000000为-128。如:byte类型的-1是11111111

e.printStackTrace():

public void printStackTrace()将此 throwable 及其追随输出至标准错误流。此方法将此
Throwable 对象的堆栈跟随输出至错误输出流,作为字段 System.err 的值。
当try语句里出现异常时,会执行catch里的语句,java运行时系统会自动将catch括号里的Exception e 初始操作,也就是实例操作Exception类型的对象。e是此对象引用名称。然后e(引用)会自动调用Exception类里指定的方法,也就出现了e.printStackTrace() ;。
printStackTrace()方法的意思是:在命令行打印异常信息在程序里出错的位置及原因。

trim():

主要有2个用法:1、就是去掉字符串里前后的空白;这个方法的主要可以使用在判断用户输入的密码之类的。2、它不仅可以去除空白,还可以去除字符串里的制表符

equalsIgnoreCase():

equalsIgnoreCase() 方法用于将字符串与指定的对象比较,不考虑大小写。
如果给定对象与字符串相等,则返回 true,否则返回 false。
equals() 会判断大小写区别,equalsIgnoreCase() 不会判断大小写区别:

First_Mobile题目:

getByte():

功能:返回字符的ascii码值
不同于getBytes(),getBytes()方法是得到一个操作系统默认的编码格式的字节数组。

equals():

功能:用于将字符串与指定的对象比较。
结果:相等时返回true,反之返回false

getApplicationContext():

同上

LoopAndLoop题目:

Integer.parseInt():

这个方法是将字符串转换为整型
方法解析字符串参数s为有符号十进制整数。
将String字符类型数据转换为Integer整型数据

.so文件:

Android里的so文件是动态链接库,是二进制文件,即ELF文件。多用于NDK开发里。

_JNIEnv::GetMethodID:

GetFieldID是得到java类里的参数ID,GetMethodID得到java类里方法的ID,它们只能调用类里声明为 public的参数或方法。

_JNIEnv::CallIntMethod:

得到java类里Int类型的方法

SafeBox题目:

Math.abs():

abs() 返回参数的绝对值。参数可以是 int, float, long, double, short, byte类型。

easy-100题目:

new:

在Java里,new关键字被使用来创建一个新的对象,可以理解为创建的意思。使用关键字new来创建一个对象也叫类的实例化。关键字 new 意味着内存的分配和初始操作,new 调用的方法就是类的构造方法。
Byte a[] = new byte[1024]
new其实就是创建一个新的熟悉,在内存里开辟一个空间。new 就是创建一个对象的意思。这里new就是创建一个byte数组,byte[1024]是数组长度为1024
byte byt[] = new byte[1024]; //1024是什么意思
这里的1024是一个数字,表示这个byte数组的长度。
// 推荐这么写,你看main方法就知道String[] args 而不是 String args[]
byte[] byt = new byte[1024];

new String(XXX,UTF-8):
str.getBytes(UTF-8); 的意思是以UTF-8的编码取得字节
new String(XXX,UTF-8); 的意思是以UTF-8的编码生成字符串

new String(“参数”):
String str3 = new String(“abcd”)的实现过程:直接在堆里创建对象。如果后来又有String str4 = new String(“abcd”),str4不会指向之前的对象,而是重新创建一个对象并指向它,所以如果此时进行str3==str4返回值是false,因为两个对象的地址不一样,如果是str3.equals(str4),返回true,因为内容相同。
例如:
this.v = new String(v0_2, “utf-8”);
将v0_2数据保存在 v 字符串里。

Java 一个类调用另一个类里的方法:

如果另一个类里的那个方法是私有,就不能直接调用到,如果是其他类型的话看情况,如果是静态的(static)话,直接用类名可以调用到,如果是非静态的,就需要利用另一个类的实例(也就是用那个类生成的对象)来调用。
如:
class A{
public static void a(){}
public void b(){}
}
public class B{
public static void main(String[] args){
A.a();//静态,形式为类名.方法名()
new A().b();//非静态,形式为类名().方法名()
}
}
Puppy myPuppy = new Puppy( “tommy” );
注意:创建对象Puppy为类名
在这里插入图片描述
MainActivity.a(this.a, MainActivity.a(this.a), this.a.getText().toString())
其里第一个参数是句柄,第二个参数是调用了 a 函数(另外一个a)返回一个字符串,第三个参数是我们输入的字符串。

getApplicationInfo():

ApplicationInfo是android.content.pm包下的一个实体类,用于封装应用的信息,flags是其里的一个成员变量public int flags = 0;用于保存应用的标志信息。
ApplicationInfo 通过它可以得到一个应用基本信息。这些信息是从AndroidManifest.xml的< application >标签获取的
以ApplicationInfo的实例对象info为例
系统应用 -> info.flags & ApplicationInfo.FLAG_SYSTEM == ApplicationInfo.FLAG_SYSTEM
解读:ApplicationInfo.FLAG_SYSTEM 是二进制1左移0位,还是1,flags & 1 = 1,则flags的二进制末位需为1,
因此只有flags是奇数,对应的应用才会是系统应用。其他的属性用法类同。

InputStream:

在java里InputStream是字节输入流,用来将文件里的数据读取到java程序里。
InputStream为所有字节输入流的顶层父类,是一个抽象类。如果要用,需要使用子类。
InputStream这个抽象类是所有基于字节的输入流的超类,抽象了Java的字节输入模型。

getResources():

getResources()这类方法就能够获取存在系统的资源
比如:把资源文件放到应用程序的/raw/raw下。那么就能够在应用里通过getResources获取资源后。以openRawResource方法(不带后缀的资源文件名称)打开这个文件
InputStream openRawResource(int id) 获取资源的数据流,读取资源数据
把一个图片资源,添加你的文件到你工程里res/drawable/目录里去,可以在代码或XML布局里,引用它也可以用资源编号,比如你选择一个文件只要去掉后缀就可以了(例如:mmm_image.png 引用它是就是mm_image)。
当需要使用的xml资源的时候,就可以使用context.getResources().getDrawable(R…资源的地址如:R.String.ok);
当你方法里面没有Context参数,可以 this.getContext().getResources();这样就可以了。

getAssets():

getAssets():访问资产目录
assets文件夹里面的文件都是保持原本的文件格式,需要用AssetManager以字节流的形式读取文件。assets的读取方式:先在Activity里面调用getAssets() 来获取。

available():

要一次读取多个字节时,经常用到InputStream.available()方法,这个方法可以在读写操作前先得知数据流里有多少个字节可以读取。

read():

read() : 从输入流里读取数据的下一个字节,返回0到255范围内的int字节值。如果因为已经到达流末尾而没有可用的字节,则返回-1。在输入数据可用、检测到流末尾或者抛出异常前,此方法一直阻塞。
read(byte[] b) : 从输入流里读取一定数量的字节,并将其存储在缓冲区数组 b 里。以整数形式返回实际读取的字节数。在输入数据可用、检测到文件末尾或者抛出异常前,此方法一直阻塞。
如果 b 的长度为 0,则不读取任何字节并返回 0;否则,尝试读取至少一个字节。如果因为流位于文件末尾而没有可用的字节,则返回值 -1;否则,至少读取一个字节并将其存在 b 里。
将读取的第一个字节存储在元素 b[0] 里,下一个存储在 b[1] 里,依次类推。读取的字节数最多等于b 的长度。设 k 为实际读取的字节数;这些字节将存储在 b[0] 到 b[k-1] 的元素里,不影响 b[k] 到b[b.length-1] 的元素。

System.arraycopy:

System.arrayCopy的源代码声明 :
public static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length)
代码解释:
  Object src : 原数组
int srcPos : 从原数据的起始位置开始
  Object dest : 目标数组
  int destPos : 目标数组的开始起始位置
  int length : 要copy的数组的长度
比如 :我们有一个数组数据 byte[] srcBytes = new byte[]{2,4,0,0,0,0,0,10,15,50}; // 源数组
byte[] destBytes = new byte[5]; // 目标数组
我们使用System.arraycopy进行转换(copy)

System.arrayCopy(srcBytes,0,destBytes ,0,5)
上面这段代码就是 : 创建一个一维空数组,数组的长度为 12位,然后将srcBytes源数组里 从0位 到 第5位之间的数值 copy 到 destBytes目标数组里,在目标数组的第0位开始放置.
那么这行代码的运行效果应该是 2,4,0,0,0,

implements:

关键字implements是一个类,实现一个接口用的关键字,它是用来实现接口里定义的抽象方法。实现一个接口,需实现接口里的所有方法。使用 implements 关键字可以变相的令java具有多继承的特性,使用范围为类继承接口的情况,可以同时继承多个接口(接口跟接口之间采用逗号分隔)
还有几点需要注意:
(1)接口可以被多重实现(implements),抽象类只能被单一继承(extends)
(2)接口只有定义,抽象类可以有定义和实现
(3)接口的字段定义默认为:public static final, 抽象类字段默认是”friendly”(本包可见)

SecretKeySpec:

目前主流的加密方式有:(对称加密)AES、DES (非对称加密)RSA、DSA
SecretKeySpec类是KeySpec接口的实现类,用于构建秘密密钥规范。可根据一个字节数组构造一个SecretKey,而无须通过一个(基于provider的)SecretKeyFactory。
//根据字节数组生成AES密钥
this.a = new SecretKeySpec(arg1, “AES”);

MessageDigest:
MessageDigest 主要是用于数据加密
java.security.MessageDigest类用于为应用程序提供信息摘要算法的功能,如 MD5 或 SHA 算法。简单点说就是用于生成散列码。信息摘要是安全的单向哈希函数,它接收随意大小的数据,输出固定长度的哈希值。
MessageDigest 通过其getInstance系列静态函数来进行实例操作和初始操作。MessageDigest 对象通过update 方法处理数据。不论什么时候都能够调用reset 方法重置摘要。一旦全部须要更新的数据都已经被更新了,应该通过digest 方法里的一个完毕哈希计算并返回结果。
对于给定数量的更新数据,digest 方法仅仅能被调用一次。digest 方法被调用后,
MessageDigest 对象被又一次设置成其初始状态。

MessageDigest(String algorithm):
创建具有指定算法名称的MessageDigest 实例对象。
getInstance(String algorithm):
生成实现指定摘要算法的 MessageDigest 对象。
getInstance(String algorithm,Provider provider):
生成实现指定提供程序提供的指定算法的 MessageDigest 对象,假设该算法可从指定的提供程序得到。
getInstance(String algorithm,String provider):
生成实现指定提供程序提供的指定算法的 MessageDigest 对象,假设该算法可从指定的提供程序得到。
digest():
通过运行诸如填充之类的操作完成哈希计算。
digest(byte[] input):
通过指定的字节数组对摘要进行最后更新,然后完成摘要计算。
digest(byte[] buf,int offset,int len):
通过运行诸如填充之类的操作完成哈希计算。
update(byte input)
通过指定的字节更新摘要。
update(bute[] input):
通过指定的字节数组更新摘要。
update(byte[] input,int offset,int len):
通过指定的字节数组,从指定的偏移量起更新摘要。
update(ByteBuffer input):
通过指定的 ByteBuffer 更新摘要。

Cipher.getInstance(“AES/ECB/PKCS5Padding”):

该类位于javax.crypto包下,此类为加密和解密提供密码功能,它构成了 Java Cryptographic Extension (JCE) 框架的核心。
Cipher创建:
创建 Cipher 对象,应用程序调用 Cipher 的 getInstance 方法并将所请求转换的名称传递给它。还可以指定提供者的名称(可选)。
转换是一个字符串,它描述为产生某类输出而在给定的输入上执行的操作(或一组操作)。转换包括加密算法的名称(例如AES,DES),后面可能跟有一个反馈模式和填充方案。如以下形式:
“算法/模式/填充”或“算法”(后一类情况下,使用模式和填充方案特定于提供者的默认值)。例如:
//根据指定算法AES生成成密码器
Cipher cipher = Cipher.getInstance(“AES/ECB/PKCS5Padding”);
Cipher cipher = Cipher.getInstance(“DES”);

goto:

跳出多重循环
在这里插入图片描述
跳转的时候,直接跳过了这个循环

init():

init() 方法是初始操作方法,用于在启动Applet程序之前做一些需要的工作
Java对象在被创建时,会进行实例操作操作。该部分操作封装在方法里,并且子类的方法里会首先对父类方法的调用。
init是对象构造器方法,也就是说在程序执行 new 一个对象调用该对象类的 constructor 方法时才会执行init方法。

doFinal():

属于java.security和javax.crypto包下的类
此方法结束单部分加密或者解密操作。
此方法接收需要加密或者解密的完整报文,返回处理结果
此方法正常调用结束之后Cipher会重置为初始操作状态。

例题:
加密算法:
在这里插入图片描述
在这里插入图片描述
解密算法:
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值