第一周

1. 详细描述登录注册流程



1.在有数据的情况下,搭建页面,分别有登录和注册两个按钮,点击注册按钮进入注册页面,输入相关的注册信息以及验证码,判断这些数据是否为空或者不符合规定(比如密码与重复密码不同,验证码错误或者为空),如果不符合则返回一条错误信息提示用户修改,如果符合则完成注册。

2.进入登录页面,输入相关登录信息,判断返回值是否为空,如果为空则表示没有这个用户(输入信息有误或去注册),还有得到的这些数据是否为空或者不符合逻辑,如果为空或格式错误,返回一条错误信息,如果符合规定,再判断当前输入的密码和之前表单中的密码是否相同,如相同,则登录成功进入app。

2.Android 的几种加密的方式  概念以及使用


1.MD5加密

MD5本质是一种散列函数,用以提供消息的完整性保护。 

特点:

        1.压缩性:任意长度的数据,算出的MD5的值都是固定的。

        2.容易计算:从原数据计算出MD5值很容易

        3.抗修改性:对原数据进行任何改动,哪怕是修改一个字节,得到的MD5值都有很大区别。

        4.强抗碰撞:已知原数据和其MD5值,想找到一个具有相同MD5值的数据(即伪造数据)是相当困难的。

        5.不可逆:MD5理论上是不可逆的(但是现在可以暴力破解了)

使用场景

        1.验证密码:只要算法不变,就能和服务器上的MD5匹配 。

        2.文件完整性的效验:当下载文件时,服务器返回的信息包括这个文件的MD5,在本地下载完毕时进行MD5加密将两个MD5值进行比较,如果相等则表示文件完整没有丢包现象。

 工具类代码:

        package comvoice.example.zhangbin.md5codedemo.utils;

        import java.io.File;

        import java.io.FileInputStream;

        import java.io.FileNotFoundException;

        import java.io.IOException;

        import java.io.UnsupportedEncodingException;

        import java.security.DigestInputStream;

        import java.security.MessageDigest;

        import java.security.NoSuchAlgorithmException;

//MD5加密

public class MD5Utils {

    //加密字符串

    public String getMD5Code(String info){

        try {

            MessageDigest md5=MessageDigest.getInstance("MD5");

            md5.update(info.getBytes("utf-8"));

            byte[]encryption=md5.digest();

            StringBuffer stringBuffer=new StringBuffer();

            for(int i=0;i<encryption.length;i++){

                if(Integer.toHexString(0xff &encryption[i]).length()==1){

                    stringBuffer.append("0").append(Integer.toHexString(0xff&encryption[i]));

                }else {

                    stringBuffer.append(Integer.toHexString(0xff&encryption[i]));

                }

            }

            return stringBuffer.toString();

        } catch (Exception e) {

//            e.printStackTrace();

            return "";

        }

    }

    //加密文件

    public static String md5ForFile(File file){

        int buffersize = 1024;

        FileInputStream fis = null;

        DigestInputStream dis = null;

        try {

            //创建MD5转换器和文件流

            MessageDigest messageDigest =MessageDigest.getInstance("MD5");

            fis = new FileInputStream(file);

            dis = new DigestInputStream(fis,messageDigest);

            byte[] buffer = new byte[buffersize];

            //DigestInputStream实际上在流处理文件时就在内部就进行了一定的处理

            while (dis.read(buffer) > 0);

            //通过DigestInputStream对象得到一个最终的MessageDigest对象。

            messageDigest = dis.getMessageDigest();

            // 通过messageDigest拿到结果,也是字节数组,包含16个元素

            byte[] array = messageDigest.digest();

            // 同样,把字节数组转换成字符串

            StringBuilder hex = new StringBuilder(array.length * 2);

            for (byte b : array) {

                if ((b & 0xFF) < 0x10){

                    hex.append("0");

                }

                hex.append(Integer.toHexString(b & 0xFF));

            }

            return hex.toString();

        } catch (FileNotFoundException e) {

            e.printStackTrace();

        } catch (NoSuchAlgorithmException e) {

            e.printStackTrace();

        } catch (IOException e) {

            e.printStackTrace();

        }

        return null;

    }

}

   

 2.RSA加密

        RSA加密算法是一种非对称的算法,非对称算法需要两个密钥,一个公共密钥一个私有密钥,公共密钥和私有密钥是配对的,用公共密钥加密的数据只有配对的私有密钥才能解密。

        RSA对加密数据的长度有限制,一般为11,如加密数据过长,可以采用数据截取的方法,分段加密。

    使用场景:

        文件或数据在本地使用公共密钥和私有密钥进行加密,然后传到服务器,服务器用同一套密钥中的公共密钥或私有密钥解密。

    代码:

import android.util.Base64;

import java.security.InvalidKeyException;

import java.security.Key;

import java.security.KeyPair;

import java.security.KeyPairGenerator;

import java.security.NoSuchAlgorithmException;

import java.security.PrivateKey;

import java.security.PublicKey;

import javax.crypto.Cipher;

import javax.crypto.NoSuchPaddingException;

public class RSAUtils {

    //构建Cipher实例时所传入的的字符串,默认为"RSA/NONE/PKCS1Padding"

    private static String sTransform = "RSA/NONE/PKCS1Padding";

    //进行Base64转码时的flag设置,默认为Base64.DEFAULT

    private static int sBase64Mode = Base64.DEFAULT;

    //初始化方法,设置参数

    public static void init(String transform,int base64Mode){

        sTransform = transform;

        sBase64Mode = base64Mode;

    }

    //产生密钥对

    public static KeyPair generateRSAKeyPair(int keyLength){

        KeyPair keyPair=null;

        try {

            KeyPairGenerator keyPairGenerator=KeyPairGenerator.getInstance("RSA");

            //设置密钥长度

            keyPairGenerator.initialize(keyLength);

            //产生密钥对

            keyPair=keyPairGenerator.generateKeyPair();

        } catch (NoSuchAlgorithmException e) {

            e.printStackTrace();

        }

        return keyPair;

    }

    /**

    * 加密或解密数据的通用的方法,srcData:待处理的数据;key:公钥或者私钥,mode指

    * 加密还是解密,值为Cipher.ENCRYPT_MODE或者Cipher.DECRYPT_MODE

    */

    public static byte[]processDAta(byte[]srcData, Key key,int mode){

        //用来保存处理的结果

        byte[]resultBytes=null;

        //构建Cipher对象,需要传入一个字符串,格式必须为"algorithm/mode/padding"或者"algorithm/",意为"算法/加密模式/填充方式"

        try {

            Cipher cipher=Cipher.getInstance("RSA/NONE/PKCS1Padding");

            //初始化Cipher,mode指定是加密还是解密,key为公钥或密钥

            cipher.init(mode,key);

            //处理数据

            resultBytes=cipher.doFinal(srcData);

        } catch (Exception e) {

            e.printStackTrace();

        }

        return resultBytes;

    }

    //使用公钥加密数据,结果用Base64转码

    public static String encryptDataByPublicKey(byte[]srcData, PublicKey publicKey){

        byte[]resultBytes=processDAta(srcData,publicKey,Cipher.ENCRYPT_MODE);

        return Base64.encodeToString(resultBytes,sBase64Mode);

    }

    //使用私钥解密,结果用Base64转码

    public static byte[]decryptDataByPrivate(String encryptedData, PrivateKey privateKey){

        byte[]bytes=Base64.decode(encryptedData,sBase64Mode);

        return processDAta(bytes,privateKey,Cipher.DECRYPT_MODE);

    }

    //使用私钥解密,返回解码数据

    public static String decryptToStrByPrivate(String encryptedData,PrivateKey privateKey){

        return new String(decryptDataByPrivate(encryptedData,privateKey));

    }

}

  3.AES加密

            AES加密是一种高级加密标准,是一种区块加密标准,它是一个对称密码,也就是说加密和解密用的是同一个密钥,WPA/WPA2经常用的加密方式就是AES。

     示意图:


    工具类代码:

        import java.io.UnsupportedEncodingException;

        import javax.crypto.Cipher;

        import javax.crypto.spec.SecretKeySpec;

        public class AESUtils3 {

            /*  算法/模式/填充 */

        private static final String CipherMode = "AES/ECB/PKCS5Padding";

               /*  创建密钥  */

        private static SecretKeySpec createKey(String password) {

        byte[] data = null;

        if (password == null) {

            password = "";

        }

        StringBuffer sb = new StringBuffer(32);

        sb.append(password);

        while (sb.length() < 32) {

            sb.append("0");

        }

        if (sb.length() > 32) {

            sb.setLength(32);

        }

        try {

            data = sb.toString().getBytes("UTF-8");

        } catch (UnsupportedEncodingException e) {

            e.printStackTrace();

        }

        return new SecretKeySpec(data, "AES");

    }

    /* 加密字节数据  */

    public static byte[] encrypt(byte[] content, String password) {

        try {

            SecretKeySpec key = createKey(password);

            System.out.println(key);

            Cipher cipher = Cipher.getInstance(CipherMode);

            cipher.init(Cipher.ENCRYPT_MODE, key);

            byte[] result = cipher.doFinal(content);

            return result;

        } catch (Exception e) {

            e.printStackTrace();

        }

        return null;

    }

    /*加密(结果为16进制字符串)  */

    public static String encrypt(String content, String password) {

        byte[] data = null;

        try {

            data = content.getBytes("UTF-8");

        } catch (Exception e) {

            e.printStackTrace();

        }

        data = encrypt(data, password);

        String result = byte2hex(data);

        return result;

    }

    /*解密字节数组*/

    public static byte[] decrypt(byte[] content, String password) {

        try {

            SecretKeySpec key = createKey(password);

            Cipher cipher = Cipher.getInstance(CipherMode);

            cipher.init(Cipher.DECRYPT_MODE, key);

            byte[] result = cipher.doFinal(content);

            return result;

        } catch (Exception e) {

            e.printStackTrace();

        }

        return null;

    }

    /*解密16进制的字符串为字符串  */

    public static String decrypt(String content, String password) {

        byte[] data = null;

        try {

            data = hex2byte(content);

        } catch (Exception e) {

            e.printStackTrace();

        }

        data = decrypt(data, password);

        if (data == null) return null;

        String result = null;

        try {

            result = new String(data, "UTF-8");

        } catch (UnsupportedEncodingException e) {

            e.printStackTrace();

        }

        return result;

    }

    /*字节数组转成16进制字符串  */

    public static String byte2hex(byte[] b) { // 一个字节的数,

        StringBuffer sb = new StringBuffer(b.length * 2);

        String tmp = "";

        for (int n = 0; n < b.length; n++) {

            // 整数转成十六进制表示

            tmp = (java.lang.Integer.toHexString(b[n] & 0XFF));

            if (tmp.length() == 1) {

                sb.append("0");

            }

            sb.append(tmp);

        }

        return sb.toString().toUpperCase(); // 转成大写

    }

    /*将hex字符串转换成字节数组 */

    private static byte[] hex2byte(String inputString) {

        if (inputString == null || inputString.length() < 2) {

            return new byte[0];

        }

        inputString = inputString.toLowerCase();

        int l = inputString.length() / 2;

        byte[] result = new byte[l];

        for (int i = 0; i < l; ++i) {

            String tmp = inputString.substring(2 * i, 2 * i + 2);

            result[i] = (byte) (Integer.parseInt(tmp, 16) & 0xFF);

        }

        return result;

    }

}




3.Handle运用场景

        1.利用Looper.prepare()初始化Looper

        2.创建Handler,其中Handler构造方法可以传入相关参数实现一些特殊的功能

        3.执行 Looper.loop()方法,开始从消息队列中取出消息,利用Handler的dispatchMessage方法进行分发

        4.Handle通过post,sendMessage等方法,发送消息,其实就是将Message添加到MessageQueue中

        5.Handler通过handleMessage方法处理接收到的Message

        


4.Handle原理

        1.首先我们得知道Handler,Looper,Message Queue三者之间的关系

             Handler封装了消息的发送,也负责接收消。内部会跟Looper关联。

            Looper 消息封装的载,内部包含了MessageQueue,负责从MessageQueue取出消息,然后交给Handler处理

            MessageQueue 就是一个消息队列,负责存储消息,有消息过来就存储起来,Looper会循环的从MessageQueue读取消息。

          2.总结

            总结:handler负责发送消息,Looper负责接收Handler发送的消息,并直接把消息回传给Handler自己。MessageQueue就是一个存储消   息的容器。



©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,919评论 6 502
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,567评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,316评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,294评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,318评论 6 390
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,245评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,120评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,964评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,376评论 1 313
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,592评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,764评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,460评论 5 344
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,070评论 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,697评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,846评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,819评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,665评论 2 354

推荐阅读更多精彩内容