天天看点

互联网面试-关于摘要算法之MD5算法和SHA1算法?

作者:架构师面试宝典
互联网面试-关于摘要算法之MD5算法和SHA1算法?

这篇文章我们主要来介绍一些常用的摘要算法,常见的摘要算法有MD5、SHA-1等,以及基于这两种算法思想的变体算法。下面我们就来详细介绍一下这些算法。

摘要算法

摘要算法的主要特征就是在数据加密的过程中不需要密钥的参与,也是由于没有密钥的参与所以数据加密是无法进行破解的。只有输入相同的原始数据才可以得到加密之后的相同密文。

摘要算法的特点就是无论数据有多长,其计算出来的加密数据总是长度一定的。并且在通过原始数据计算之后,看上去是没有规律的,但是如果使用的是相同的原始数据得到的加密数据又是相同的。一旦原始数据发生的微小的变化,那么经过计算得到的加密数据将是天壤之别。由于算法的不可逆的性质,所以经过加密之后得到的数据基本上是看不到任何的原始数据的相关信息的。

摘要算法由于其不可逆性,以及变化唯一性的特点,经常被用来完成数字签名操作、文件校验操作等等。而我们日常开发中常见的摘要算法有MD5、SHA1等等。

MD5算法

MD5算法的作用就是让大容量的信息在用数字签名软件签署的私人密钥前被压缩成一种保密格式,也就是通过算法将任意长度的字符串变化为一个定长的十六进制字符串。其特点有如下一些。

压缩性:任意长度的数据,最终计算得到的MD5值的长度都是固定的

容易计算:从原始数据计算的到一个MD5的值是非常容易的

抗修改性:一般我们都采用MD5编码来校验文件是否发生了变化,这是因为即使是对原始数据修改了一个字节,也会导致计算出来的MD5值与原来的值相差巨大。

抗碰撞性:假设已知原始数据与其MD5的值,想要找到一个MD5相同的数据原始值也是非常困难的。

代码实现

利用JDK提供java.security.MessageDigest类实现MD5算法:

import java.security.MessageDigest;

public class MD5Utils {

    //测试代码
    public static void main(String[] args) {
        System.out.println(getMD5Code("架构师面试宝典"));
    }
    private MD5Utils() {
    }

    // md5加密
    public static String getMD5Code(String message) {
        String md5Str = "";
        try {
        	//创建MD5算法消息摘要
            MessageDigest md = MessageDigest.getInstance("MD5");
            //生成的哈希值的字节数组
            byte[] md5Bytes = md.digest(message.getBytes());
            md5Str = bytes2Hex(md5Bytes);
        }catch(Exception e) {
            e.printStackTrace();
        }
        return md5Str;
    }

    // 2进制转16进制
    public static String bytes2Hex(byte[] bytes) {
        StringBuffer result = new StringBuffer();
        int temp;
        try {
            for (int i = 0; i < bytes.length; i++) {
                temp = bytes[i];
                if(temp < 0) {
                    temp += 256;
                }
                if (temp < 16) {
                    result.append("0");
                }
                result.append(Integer.toHexString(temp));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result.toString();
    }
}           

SHA1

对于一些长度小于2^64位的消息,SHA1会产生一个160位大约是40个字符的消息摘要。当收到这个摘要的时候,可以用这个摘要来校验收到的数据是否完整。因为在网络传输的过程中会出现各种各样的网络延迟,可能会导致丢包情况的出现。通过这种加密方式就可以来校验数据是否完整。

SHA1算法的特点

不可以从消息摘要中获取到原始信息

两个不同的消息不会产生同样的消息摘要,但是这个几率是存在的,而且非常小,可以忽略其影响。

Java代码实现

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class SHA1Demo {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		System.out.println(getSha1("架构师面试宝典"));
	}

	public static String getSha1(String str) {
		if (null == str || 0 == str.length()) {
			return null;
		}
		char[] hexDigits = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
		try {
			//创建SHA1算法消息摘要对象
			MessageDigest mdTemp = MessageDigest.getInstance("SHA1");
			//使用指定的字节数组更新摘要。
			mdTemp.update(str.getBytes("UTF-8"));
			//生成的哈希值的字节数组
			byte[] md = mdTemp.digest();
			//SHA1算法生成信息摘要关键过程
			int j = md.length;
		    char[] buf = new char[j * 2];
			int k = 0;
			for (int i = 0; i < j; i++) {
				byte byte0 = md[i];
				buf[k++] = hexDigits[byte0 >>> 4 & 0xf];
				buf[k++] = hexDigits[byte0 & 0xf];
			}
			return new String(buf);
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return "0";
		
	}
}           

总结

上面我们介绍了MD5和SHA1两种摘要算法,了解了两种算法的优势,在实际的工作中我们还会遇到很多的基于摘要算法实现的不同实现算法。在使用过程中,需要结合实际的情况来完成对于数据的加密操作。

继续阅读