加密类算法

发布于:2022-11-29 ⋅ 阅读:(162) ⋅ 点赞:(0)

目录

什么是Hash算法

Hash算法有哪些

Hash应用

什么是Hash冲突

如何解决Hash冲突


什么是Hash算法

任意长度的输入经过Hash算法转化为一定长度的输出。就像读很多本书,最终总结成一本摘要,
看书的操作可以理解为hash算法,总结一本摘要可以理解为hash值,所以hash算法也称为摘要算法或者散列算法。

Hash算法的特点

不可逆,不能通过hash值计算出原本的值。

效率高,hash算法通常能够快速的得到结果。

冲突少,优秀的hash算法应具备的条件。

Hash算法有哪些

目前流行的Hash算法包括MD5、SHA-1 和 SHA-2。

MD4(RFC 1320)是MIT的Ronald L. Rivest在1990年设计的,MD是Message Digest的缩写,其输出为128位,MD4已被证明不够安全。

MD5(RFC 1321)是Rivest于1991年对MD4的改进版本。它对输入仍以512位分组,其输出是128位。MD5比MD4复杂,计算速度要慢一点,但是更安全一些。MD5已被证明不具备"强抗碰撞性"。

SHA(Secure Hash Algorithm)是一个Hash函数族,由NIST(National Institute of Standards and Technology)于1993年发布第一个算法。
SHA-1在1995年面世,它的输出为长度160位的hash值,因此抗穷举性更好。设计时基于和MD4 相同原理,并且模仿了该算法,SHA-1已被证明不具"强抗碰撞性"。
SHA-2为了提高安全性,NIST还设计出了SHA-224、SHA-256、SHA-384和SHA-512算法(统称为 SHA-2),跟SHA-1算法原理类似。SHA-3相关算法也已被提出。

Hash应用

密码学及数字签名

登陆知乎时需要输入密码,知乎如果明文保存这个密码,黑客就很容易窃取到登录的密码,特别不安全。然后知乎就想了一个方法,使用hash算法生成一个密码的签名,知乎后台只保存这个签名值。由于hash算法是不可逆的,黑客即便拿到这个签名也没用。在网站登陆界面上输入密码,知乎后台会重新计算一下这个hash值,与网站中储存的原hash值进行比对,如果相同,证明你拥有这个账户的密码,就会允许登陆。

文件完整性校验 

//两段字节串,注意它们有细微差别
a = bytearray.fromhex("0e306561559aa787d00bc6f70bbdfe3404cf03659e704f8534c00ffb659c4
            c8740cc942feb2da115a3f4155cbb8607497386656d7d1f34a42059d78f5a8dd1ef")
b = bytearray.fromhex("0e306561559aa787d00bc6f70bbdfe3404cf03659e744f8534c00ffb659c4
            c8740cc942feb2da115a3f415dcbb8607497386656d7d1f34a42059d78f5a8dd1ef")

//输出MD5
print(hashlib.md5(a).hexdigest())
print(hashlib.md5(b).hexdigest())

//a和b输出结果都为:
cee9a457e790cf20d4bdaa6d69f01e41
cee9a457e790cf20d4bdaa6d69f01e41

文件内容a和b有细微的修改,得到的hash值应该不一样才对,所以MD5在数年前就已经不被推荐作为应用中的散列算法方案,取代它的是SHA家族算法,也就是安全散列算法(Secure Hash Algorithm,缩写为SHA) 。

JAVA中基于Hash的数据结构

HashMap是对Array与Link的折衷处理,Array与Link可以说是两个速度方向的极端,Array注重于数据的获取,而添加/删除的效率非常低,Link由于是每个对象都保持着下一个对象的指针,查找某个数据需要遍历之前所有的数据,效率比较低,在修改操作中比较快。

JDK1.8HashMap中Hash值的计算

 static final int hash(Object key) {
        int h;
        //计算hashCode
        return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
    }

Java中几个常用的哈希码(hashCode)算法

Object类的hashCode:返回的是经过处理后的内存地址,由于每个对象的内存地址都不一样,所以哈希码也不一样。这个是native方法,取决于JVM的内部设计,一般是某种C地址的偏移。
String类的hashCode:根据字符串的内容返回哈希码,只要字符串的内容相同,返回的哈希码也相同,JDK1.8中的String.hashCode()如下:

public int hashCode() {
        int h = hash;
        //hash default value : 0
        if (h == 0 && value.length > 0) {
            //value : char storage
            char val[] = value;
            for (int i = 0; i < value.length; i++) {
                h = 31 * h + val[i];
            }
            hash = h;
        }
        return h;
    }

Integer等包装类,返回的哈希码就是Integer对象里包含的那个整数的数值。

Integer n=new Integer(100);
//n.hashCode的值就是100 

由此可见,两个一样大小的Integer对象,返回的哈希码也一样 。

什么是Hash冲突

当Key值利用Hash算法定位到数组的某个位置,该位置已经有值时,就会产生冲突,称为Hash冲突。

如何解决Hash冲突

链地址法:利用链表解决。

开放地址法:向下线性或者随机探测不冲突的地址。

再Hash法:通过多个hash算法重新定位。

本文含有隐藏内容,请 开通VIP 后查看

网站公告


今日签到

点亮在社区的每一天
去签到