哈希算法的简单理解

哈希算法基本内容

概述

哈希算法(Hash)又称摘要算法(Digest),它的作用是:对任意一组输入数据进行计算,得到一个固定长度的输出摘要。

特点

  • 相同的输入一定得到相同的输出;
  • 不同的输入大概率得到不同的输出;

目的

为了验证原始数据是否被篡改。

哈希碰撞

两个不同的输入得到了相同的输出。
例如:

"AaAaAa".hashCode(); // 0x7460e8c0 
"BBAaBB".hashCode(); // 0x7460e8c0 
 
"通话".hashCode(); // 0x11ff03 
"重地".hashCode(); // 0x11ff03

注意:
哈希碰撞不能避免。
原因:哈希算法是把一个无限的输入集合映射到一个有限的输出集合,输入的字节长度固定,必然会产生碰撞。

安全的哈希算法

碰撞的高低概率关系到哈希算法的安全性。

安全的哈希算法需要满足的条件

  • 碰撞概率低
  • 不能被猜测出

常用的哈希算法

MD5

  • 输出长度(位):128 bits
  • 输出长度(字节):16 bytes

基于MD5算法对数据进行加密

//创建基于MD5算法的消息摘要对象
MessageDigest md5 = MessageDigest.getInstance("MD5");

//更新原始数据
md5.update("天王盖地虎宝塔镇河妖".getBytes());

//获取加密后的结果
byte[] digestBytes = md5.digest();
System.out.println("加密后的结果(字节数组):" + Arrays.toString(digestBytes));
System.out.println("加密后的结果(16进制字符串):" + HashTools.bytesToHex(digestBytes));
System.out.println("加密后的长度:" + digestBytes.length);

基于MD5算法对图片进行“加密”

//图片的原始字节内容
byte[] imageBuf = Files.readAllBytes(Paths.get("D:\\seventeen\\1.jpg"));

//创建基于MD5算法的消息摘要对象
MessageDigest md5 = MessageDigest.getInstance("MD5");

//原始字节内容(图片)
md5.update(imageBuf);

//获取加密摘要
byte[] digestBytes = md5.digest();
System.out.println("加密后的结果(字节数组):" + Arrays.toString(digestBytes));
System.out.println("加密后的结果(16进制字符串):" + HashTools.bytesToHex(digestBytes));
System.out.println("加密后的长度:" + digestBytes.length);

注:
需通过随机加盐,解决彩虹表攻击问题

SHA-1

  • 输出长度(位):160 bits
  • 输出长度(字节):20 bytes

基于SHA-1算法对数据进行加密

//原始密码
String password = "seventeen";

//随机产生的盐值
String salt = UUID.randomUUID().toString().substring(0,4);

//创建基于SHA-1算法的消息摘要对象
MessageDigest sha1 = MessageDigest.getInstance("SHA-1");
sha1.update(password.getBytes());
sha1.update(salt.getBytes());

//计算结果加密,SHA-1的输出结果为20个字节(40个字符)
String digestHex = HashTools.bytesToHex(sha1.digest());
System.out.println(digestHex);

RipeMD-160

  • 输出长度(位):160 bits
  • 输出长度(字节):20 bytes

SHA-256

  • 输出长度(位):256 bits
  • 输出长度(字节):32 bytes

SHA-512

  • 输出长度(位):512 bits
  • 输出长度(字节):64 bytes

Hash算法(消息摘要算法)工具类

public class HashTools {

    //消息摘要对象
    private static MessageDigest digest;

    //构造方法私有
    private HashTools() {}

    //将字节数组转换为16进制字符串
    public static String bytesToHex(byte[] bytes) {
        StringBuilder ret = new StringBuilder();
        for (byte b : bytes){
            //将字节值转换为2位十六进制字符串
            ret.append(String.format("%02x", b));
        }
        return ret.toString();
    }

    //按照MD5进行消息摘要计算(哈希计算)
    public static String digestByMD5(String source) throws NoSuchAlgorithmException {
        digest = MessageDigest.getInstance("MD5");
        return handler(source);
    }

    //按照SHA-1进行消息摘要计算(哈希计算)
    public static String digestBySHA1(String source) throws NoSuchAlgorithmException {
        digest = MessageDigest.getInstance("SHA-1");
        return handler(source);
    }

    //通过消息摘要对象,处理加密内容
    private static String handler(String source){
        digest.update(source.getBytes());
        byte[] bytes = digest.digest();
        String hash = bytesToHex(bytes);
        return hash;
    }
}

总结

  • 哈希算法是单向的,只能进行加密,不能进行解密。
  • 哈希算法可用于校验下载文件。
  • 哈希算法可用于存储用户密码。
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值