写点什么

哈希游戏开发竞猜系统哈希值 hash 算法

  • 2022 年 6 月 02 日
  • 本文字数:1081 字

    阅读完需:约 4 分钟

哈希游戏开发竞猜系统哈希值hash算法

哈希算法(Hash)又称摘要算法(Digest),它的作用是:对任意一组输入数据进行计算,得到一个固定长度的输出摘要。哈希游戏开发询李:132 薇 4z77 掂 z558,哈希竞猜游戏系统搭建开发


哈希算法最重要的特点就是:


相同的输入一定得到相同的输出;


不同的输入大概率得到不同的输出。


哈希算法的目的就是为了验证原始数据是否被篡改。


Java 字符串的 hashCode()就是一个哈希算法,它的输入是任意字符串,输出是固定的 4 字节 int 整数:


"hello".hashCode();//0x5e918d2


"hello,java".hashCode();//0x7a9d88e8


"hello,bob".hashCode();//0xa0dbae2f


两个相同的字符串永远会计算出相同的 hashCode,否则基于 hashCode 定位的 HashMap 就无法正常工作。这也是为什么当我们自定义一个 class 时,覆写 equals()方法时我们必须正确覆写 hashCode()方法。


哈希碰撞


哈希碰撞是指,两个不同的输入得到了相同的输出:


"AaAaAa".hashCode();//0x7460e8c0


"BBAaBB".hashCode();//0x7460e8c0


有童鞋会问:碰撞能不能避免?答案是不能。碰撞是一定会出现的,因为输出的字节长度是固定的,String 的 hashCode()输出是 4 字节整数,最多只有 4294967296 种输出,但输入的数据长度是不固定的,有无数种输入。所以,哈希算法是把一个无限的输入集合映射到一个有限的输出集合,必然会产生碰撞。


碰撞不可怕,我们担心的不是碰撞,而是碰撞的概率,因为碰撞概率的高低关系到哈希算法的安全性。一个安全的哈希算法必须满足:


碰撞概率低;


不能猜测输出。


不能猜测输出是指,输入的任意一个 bit 的变化会造成输出完全不同,这样就很难从输出反推输入(只能依靠暴力穷举)。假设一种哈希算法有如下规律:


hashA("java001")="123456"


hashA("java002")="123457"


hashA("java003")="123458"


那么很容易从输出 123459 反推输入,这种哈希算法就不安全。安全的哈希算法从输出是看不出任何规律的:


hashB("java001")="123456"


hashB("java002")="580271"


hashB("java003")=???


根据碰撞概率,哈希算法的输出长度越长,就越难产生碰撞,也就越安全。


Java 标准库提供了常用的哈希算法,并且有一套统一的接口。我们以 MD5 算法为例,看看如何对输入计算哈希:


importjava.math.BigInteger;


importjava.security.MessageDigest;


publicclassMain{


publicstaticvoidmain(String[]args)throwsException{


//创建一个 MessageDigest 实例:


MessageDigestmd=MessageDigest.getInstance("MD5");


//反复调用 update 输入数据:


md.update("Hello".getBytes("UTF-8"));


md.update("World".getBytes("UTF-8"));


byte[]result=md.digest();//16bytes:68e109f0f40ca72a15e05cc22786f8e6


System.out.println(newBigInteger(1,result).toString(16));


}


}

用户头像

技术开发咖 2020.10.28 加入

区块链开发技术观察员

评论

发布
暂无评论
哈希游戏开发竞猜系统哈希值hash算法_哈希算法_薇電13242772558_InfoQ写作社区