一、实验题目
编写注册程序AppCracking
二、预备知识
略。
三、实验操作过程及实验结果
AppCracking程序的编写
程序功能:
在一个输入框中输入用户名,在另一个输入框中输入16位长度的注册码,然后点击注册按钮,若注册码与输入用户名匹配,则弹出“注册成功”,否则,弹出“注册失败”。
首先,我们在Android studio上建立一个新的工程。给工程命名为AppCracking,选择合适的路径。
保持默认设置就可以,直接next。
由于图形界面需要我们自己设计,所以在这里我选择Empty Activity。
给Activity命名,这里我命名为AppCracking。
点击Finish,到此为止,我们新建了一个名为AppCracking的空的工程。
接下来我们进入界面,然后点击,进行图形界面的设计。
在Palette中选择合适的按钮或者文本框拖到界面里进行设计。同时可以通过Component Tree协助设计。
可以在右侧Attributes中更改文本框中文本内容、字体等元素,通过调整使界面更加合适。例如,使“AppCracking”居中的方法使在AppCracking之前留出足够的空格,通过和界面的比对,对文本进行操作。
设计好之后的界面如下图所示。
当我们启动手机后,效果如下图所示。
至此,图形界面设计完毕。
但是,这只是一个界面,点击SIGN IN并不会有任何反应。接下来我们开始对内部设计。
首先需要安装插件butterknife。
打开File中的Settings,在Plugins搜索到ButterKnife 并安装。安装完根据系统提示对Android studio进行重启。
在build.gradle里添加相应的依赖:
implementation ‘com.jakewharton:butterknife:8.8.1’
annotationProcessor ‘com.jakewharton:butterknife-compiler:8.8.1’
如下图所示。
然后打开,对activity_app_cracking右键,选择Generate,然后选择Generate ButterKnife Injections 。
然后勾选ID为button2 的ID,注意这里的ID名称,和代码中其实是不相符的,后来需要改。
接下来将代码加到AppCracking.java中,这时会代码有一些问题,此时是无法编译运行的。根据自己的名称设置,对代码稍作改变,主要的问题已经用红色字标出来了,将鼠标放在红色单词上,可以使用Alt+Enter快速将一些不合适的名称做改变。
接着对app下res的values中的strings.xml进行修改。
添加如下语句:
Registration failed
Registration successful
Registered"
然后编译运行,打开手机。此时再次输入用户名和注册码,点击“SIGN IN”,得到回应“Registration failed”,这说明这个AppCracking已经编写完毕。
五、源代码
package cn.wyq.appcracking;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
public class AppCracking extends AppCompatActivity {
@BindView(R.id.textView13)
TextView textView13;
@BindView(R.id.textView14)
TextView textView14;
@BindView(R.id.textView15)
TextView textView15;
@BindView(R.id.textView16)
TextView textView16;
@BindView(R.id.textView17)
TextView textView17;
@BindView(R.id.etUserName)
EditText etUserName;
@BindView(R.id.textView18)
TextView textView18;
@BindView(R.id.textView20)
TextView textView20;
@BindView(R.id.etRegiserCode)
EditText etRegiserCode;
@BindView(R.id.textView22)
TextView textView22;
@BindView(R.id.textView23)
TextView textView23;
@BindView(R.id.textView19)
TextView textView19;
@BindView(R.id.btnRegister)
Button btnRegister;
@BindView(R.id.linearLayout)
LinearLayout linearLayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_app_cracking);
ButterKnife.bind(this);
btnRegister.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
if (!checkRegisterCode(etUserName.getText().toString().trim(), etRegiserCode.getText().toString().trim())) {
Toast.makeText(AppCracking.this,R.string.fail, Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(AppCracking.this, R.string.success, Toast.LENGTH_SHORT).show();
btnRegister.setEnabled(false);
setTitle(R.string.registered);
}
}
});
}
private boolean checkRegisterCode(String userName, String rs)
{
try{
if(userName==null||userName.length()==0||rs==null||rs.length()!=16)
return false;
MessageDigest digest= MessageDigest.getInstance("MD5"); //创建报文摘要实例,实现指定的摘要算法
digest.reset(); //重置摘要
digest.update(userName.getBytes()); //将String类型的字符串转化为byte类型并存入一个byte数组中
byte[] bytes=digest.digest(); //对用户名进行哈希
String hexstr = toHexString(bytes,""); //将散列值转换成十六进制的字符串
StringBuilder sb=new StringBuilder(); //取字符串前半部分所有奇数位与后半部分所有偶数位重新组合生成注册码
for(int i=0;i<hexstr.length()/2;i+=2)
{
sb.append(hexstr.charAt(i));
}
for(int i=(hexstr.length()/2+1);i<hexstr.length();i+=2)
{
sb.append(hexstr.charAt(i));
}
String userRegisterCode=sb.toString();
if(!userRegisterCode.equalsIgnoreCase(rs))
return false;
}catch(NoSuchAlgorithmException e){
e.printStackTrace();
return false;
}
return true;
}
private String toHexString(byte[] bytes, String string) {
StringBuilder hexString=new StringBuilder();
//对字符数组遍历
for(byte b:bytes)
{
/*将字节转换为16进制的字符串,不可直接对字节进行转换,字节8位,
int 32位,采用补码,直接转换出错*/
String hex=Integer.toHexString(0xFF&b);
if(hex.length()==1)
{
hexString.append('0');
}
hexString.append(hex).append(string);
}
return hexString.toString();
}
//@OnClick(R.id.button2)
//public void onViewClicked() {
//}
}