标签:close digital 数字 数字签名 基本 国际 lis node 设计
目录:
** 0x01 [哈希函数] vs [加密哈希函数]
** 0x02 [哈希碰撞] vs [生日问题]
** 0x03 [哈希表] vs [分布式哈希表]
** 0x04 [欧式距离] vs [三角不等式]
** 0x05 [异或距离] vs [前缀路由表]
在哈希表计算索引的时候,我们需要一个哈希函数,通过hash(key)来计算key在哈希表里的index。这个地方的哈希函数只要尽量满足均匀分布,周期尽量大,计算速度又足够快等即可。而在密码学里用的比较多的,则是加密哈希函数。[加密哈希函数],它需要尽量满足三个安全性质:
常见的密码哈希函数有:
其中,SHA-1因为已经在2005年可以被暴力找出碰撞,就不满足性质3,从而已经不再推荐使用了,现在常用的SHA-256,SHA-512都是属于SHA-2这个大类的,最新的则是SHA-3系列。MD5也已经在2004年就不满足强碰撞防御了,也不推荐作为密码哈希函数来用了。
加密哈希函数的使用场景,典型的有在SSL(Secure Sockets Layer)和数字签名(Digital Signature)上使用。
[1] Cryptographic hash function
[2] SHA-1
[3] SHA-2
[4] SHA-3
[5] MD5
[6] RIPEMD
一个哈希函数的取值空间是有限的,那么所有可能的结果个数是固定的,假设为D。那么,如果你能计算D+1次,自然一定有两个值发生碰撞。好在一般情况下,D都是很大的,有限算力的计算机在有生之年是没希望通过这个方式直接暴力计算出碰撞值。但是,如果我们退而求其次,只关心能否有50%的概率暴力计算出碰撞值呢?那么,你需要计算多少次后,才会有50%的概率发生碰撞?
这个问题,实际上叫做“生日问题”。在一个班级里有n个同学,每个同学的生日都只能是D=365天中的一天,那么班级里有两个人生日相同的概率P是多少呢?我们可以很容易计算出班级里所有人概率都不相同的概率P‘。计算方法是,依次计算第i个同学与前面(i-1)个同学生日都不相同的概率。那么:
从而,P‘=1x{364/365}x{363/365}x...x {(365-n+1)/365},做一个简单变换后得到:
P‘= 1x{1-1/365}x{1-2/365}x...x {1-(n-1)/365}
这样,至少有2个人生日相同的概率P = 1-P‘。推广一下,把365替换为D,则有:
P‘= 1x{1-1/D}x{1-2/D}x...x {1- (n-1)/D }
对于哈希函数来说,一般D都是很大的,例如SHA-256,可能的D的取值有2^256个,那么这个时候1/D就很小,我们可以利用e^x的泰勒公式的性质来规约P‘。具体做法是:
那么,就得到了如下的公式:
P‘= 1 x e^{-1/D} x e^{-2/D} ... x e^{-(n-1)/D}
= e^{-(1+2+...+n-1)/D}
= e^{ - n x (n-1)/2D }
进一步近似,用n^2代替 n x (n-1) 则有
再次利用当x很小时 e^x=1+x 的近似公式,就得到最后的近似值:
P = 1-e^{-n^2/2D} = 1 - (1-n^2/2D) = n^2/2D
有了这个公式,如果反算:“班级有多少人时,至少有两个人生日相同的概率是50%”,或者“哈希函数计算多少次后,有两个值碰撞的概率是50%”,我们只需要反求n即可:
n = sqrt(2D x P),把P=0.5带入,得 n = sqrt(D).
[1] Birthday problem
[2] 生日问题
[3] Birthday attack
[4] 生日攻击
[5] Collision attack
回头说两个跟哈希相关的数据结构。哈希表(Hash table)也称散列表,通过哈希函数把key映射到哈希表里的桶(bucket)的地址。由于哈希表的长度有限,通常哈希函数不可避免会发生碰撞,根据碰撞时的处理方式不同,哈希表分为两种:
对于开链法哈希表,需要哈希函数满足均匀分布,也就是哈希函数会尽量把key均匀地映射到哈希桶上。而对于开放定址法,哈希函数还要尽量减少聚集(cluster)效应导致局部哈希桶太密集,因为这会导致插入和搜索到时间变大。
相对于只考虑单机程序的哈希表,分布式哈希表(Distrubuted hash table, DHT)则构建在P2P网络上。分布式哈希表由P2P网络的节点组成,每个节点都会维护好Key被映射到的节点信息,从而实现在P2P网络里对Key-Value进行添加、查找、删除的能力。一个好的DHT需要满足下面三个性质:
DHT的结构是怎样的呢?
首先从DHT的两个基本概念入手,是最佳的方式:
在理解DHT和通常的P2P网络有什么区别之前,先看下在DHT网络上会核心做的两个操作:
上面,核心的两个动作是:
计算应该持有该key的Node有好多种算法,其中常见的一种做法就是使用一致性哈希。一致性哈希的核心做法是:
而动态查找Node实际上就是一个贪心算法:
具体关于如何“计算距离”,以及如何“设计路由表”,在Kademlia网络里有更具体的做法,下一次可以单独来讲。
[1] Hash table
[2] 哈希表
[2] Consistent hashing
[3] 一致性哈希
[4] Distributed hash table(DHT)
[5] Kademlia
[6] Overlay network
理解分布式哈希表,首先需要理解分布式哈希表里是如何计算
在介绍DHT里的距离之前,我们先看看欧几里得空间中的点是如何计算距离的。
在三维空间中,计算两个点之间的距离,叫做欧几里得距离。给定P1(x1,y1),P2(x2,y2),那么P1,P2之间的距离是sqrt(|x1-x2|^2+|y1-y2|^2)。对坐标差绝对值求平方和再开方,这个叫做2-范数距离。
有2-范数距离,当然也就有1-范数距离,公式是|x1-x2|+|y1-y2|。实际上1-范数距离也叫做“曼哈顿距离(Manhattan distance)”或者“出租车距离(Taxicab distance)”,简单说一辆出租车在曼哈顿里从一个点到另一个点,需要一直绕着格子建筑物走格子才能到达另一个点。
更一般的p-范数距离,对坐标差绝对值,先求p次方,再开p次方。也就是(|x1-x2|^p+|y1-y2|^p)^{1/p}。如果p趋向于无穷大,求极限就是无穷范数距离,也叫车比雪夫距离,国际象棋上王从一个位置要走到另一个位置所需要的步数就是车比雪夫距离。
进一步如果把P放在N维空间中,也可以用同样的方式求这些N维欧几里得空间中点的p-范数距离,此时它们统一被叫做明可夫斯基距离(Minkowski)。
有这么多种不同的距离,那么是不是两个点之间的任何函数都可以做为这两个点之间的一种“合法”的距离呢?显然不是,一个函数D要能做为欧式空间中两个点之间的距离,必须满足下面三个性质。
其中最突出的是三角不等式。实际上p-范数距离里面,p不一定要求是整数,但是如果p<1,会导致三角不等式不成立,因此p-范数要求p>=1。
有了距离,我们关心的是,可以得到下面3个DHT需要的功能:
但是DHT并不是直接使用p-范数距离,而是巧妙使用了异或(XOR)这个位操作的能力。待续。
[1] distance
[2] Minkowski distance
[3] Manhattan distance
[4] 曼哈顿距离
[5] Chebyshev distance
[6] 车比雪夫距离
编程中,在位上的操作实际上并不难理解。常见的位操作包括与(AND)、或(OR)、非(NOT)、异或(XOR),位移等。其中XOR的使用相对较少一些,但是如果理解了XOR的语义之后,就会发现XOR在操作数据方面有很大用途。
我们将一个黑白棋子保持原状看做0,将一个棋子翻转到另一面看做1,给你两次机会选择翻转或者不翻转。那么有下面几种组合:
把不翻转记为0,翻转记为1,这就是0和1的“异或”运算:
0 ⊕ 0 = 0, 0 ⊕ 1 = 1, 1 ⊕ 0 = 1, 1 ⊕ 1 = 0.
异或(XOR)在对称密码学中起着“基本操作”的作用。例如,假设明文是a,密钥是b,那么最简单的加密和解密操作分别是:
理解到翻转这个意思后,就可以活学活用了。例如,考虑一个趣题:“如何不使用临时变量交换两个变量a和b?” 这个题目有不只一种做法,先看一个只用加减法的做法:
现在,我们决定用“加解密”的方式来解决这个问题:
通过上述的几个小步骤,我们对xor的妙用有了一定的理解。回过头来,我们看下异或距离(XOR distance)这个概念。简单说,两个长度相同的二进制数据之间的异或操作,可以构成一个距离函数。也就是异或操作满足距离函数的三个重要性质:
a xor a
,每个bit上的值都相等,“翻转+翻转”或者“不翻转+不翻转”结果都等于0.有了异或距离,就可以解决P2P网络上如何把数据项(Key)存放到哪些节点(Node)的问题。一个简化的做法如下:
Node和Key构成的一致性哈希结构如图所示:
其中,比较关键的是“每个节点持有由远到近的一系列其他节点ID列表” 这个过程是如何做的。通过举例的方式,先假设节点ID如下:
现在第6个节点是110,标记为Node(6),,我们观察110节点上是如何由近到远持有其他节点ID。
根据规则3和规则4,Node(6)持有的三个list分别是:
这三个list如图中圆圈所示:
根据规则3和规则4,在计算异或距离的时候:
可以看到,每个列表里存储到其他节点确实在异或距离上是越来越近。这就是异或距离在DHT一致性哈希里的妙用。当限制每个list的容量为k时,可以动态根据节点的连通性维持每个list里的k个节点。
观察每个listi里的节点都有i-1个前缀相同,它们构成了一个前缀路由表。
[1] XOR
[2] 异或
[3] Kademlia, A P2P DHT
[4] xor distance, js code
[5] xor distance and routing table
--end--
标签:close digital 数字 数字签名 基本 国际 lis node 设计
原文地址:https://www.cnblogs.com/math/p/hash.html