PHP Implementation Consistency HASH Algorithm Example
- 2021-09-12 00:42:37
- OfStack
In this paper, an example is given to describe the 1-dimensional HASH algorithm implemented by PHP. Share it for your reference, as follows:
<?php
// +----------------------------------------------------------------------
// | Perfect Is Shit
// +----------------------------------------------------------------------
// | PHP Achieve: 1 Pathogenic HASH Algorithm
// +----------------------------------------------------------------------
// | Author: alexander <gt199899@gmail.com>
// +----------------------------------------------------------------------
// | Datetime: 2017-01-11 16:01:36
// +----------------------------------------------------------------------
// | Copyright: Perfect Is Shit
// +----------------------------------------------------------------------
class ConsistentHashing
{
// Ring
// hash -> Node
private $_ring = array();
// All nodes
// Node -> hash
public $nodes = array();
// Virtual nodes for each node
public $virtual = 64;
/**
* Structure
* @param array $nodes Initialized node list
*/
public function __construct($nodes = array())
{
if (!empty($nodes)) {
foreach ($nodes as $value) {
$this->addNode($value);
}
}
}
/**
* Get the contents of the ring
* @return array $this->_ring
*/
public function getRing()
{
return $this->_ring;
}
/**
* time33 Function
* @param string $str
* @return 32 Positive bit integer
* @author Great gods
*/
public function time33($str)
{
// hash(i) = hash(i-1) * 33 + str[i]
// $hash = 5381; ## Will hash Set to 0 Compared with setting to 5381 The distribution effect is better! ! !
$hash = 0;
$s = md5($str); // Compared with other versions, the md5 Encryption
$seed = 5;
$len = 32;// Encrypted length 32
for ($i = 0; $i < $len; $i++) {
// (hash << 5) + hash Equivalent to hash * 33
//$hash = sprintf("%u", $hash * 33) + ord($s{$i});
//$hash = ($hash * 33 + ord($s{$i})) & 0x7FFFFFFF;
$hash = ($hash << $seed) + $hash + ord($s{$i});
}
return $hash & 0x7FFFFFFF;
}
/**
* Add nodes
* @param string $node Node name
* @return object $this
*/
public function addNode($node)
{
if (in_array($node, array_keys($this->nodes))) {
return;
}
for ($i = 1; $i <= $this->virtual; $i++) {
$key = $this->time33($node . '-' . $i);
$this->_ring[$key] = $node;
$this->nodes[$node][] = $key;
}
ksort($this->_ring, SORT_NUMERIC);
return $this;
}
/**
* Object of the string HASH Nodes mapped to on the ring
* @param string $key
* @return string $node
*/
public function getNode($key)
{
$node = current($this->_ring);
$hash = $this->time33($key);
foreach ($this->_ring as $key => $value) {
if ($hash <= $key) {
$node = $value;
break;
}
}
return $node;
}
/**
* Object mapped to a specific node KEY
* This method needs to be called manually, and it is not recommended to use this method in programs without special circumstances
* @param string $node
* @param string $keyPre
* @return mixed
*/
public function getKey($node, $keyPre = ""){
if(!in_array($node, array_keys($this->nodes))){
return false;
}
$result = false;
for($i=1;$i<=10000;$i++){
$key = $keyPre . md5(rand(1000, 9999));
if($this->getNode($key) == $node){
$result = true;
break;
}
}
return $result ? $key : false;
}
}
$ch_obj = new ConsistentHashing();
$ch_obj->addNode('node_1');
$ch_obj->addNode('node_2');
$ch_obj->addNode('node_3');
$ch_obj->addNode('node_4');
$ch_obj->addNode('node_5');
$ch_obj->addNode('node_6');
// +----------------------------------------------------------------------
// | View key Nodes mapped to
// +----------------------------------------------------------------------
$key1 = "asofiwjamfdalksjfkasasdflasfja";
$key2 = "jaksldfjlasfjsdjfioafaslkjflsadkjfl";
$key3 = "asjldflkjasfsdjflkajkldsjfksajdlflajs";
$key4 = "iowanfasijfmasdnfoas";
$key5 = "pqkisndfhoalnfiewlkl";
$key6 = "qjklasjdifoajfalsjflsa";
echo sprintf("%-50s Map to Node %s\n", $key1, $ch_obj->getNode($key1));
echo sprintf("%-50s Map to Node %s\n", $key2, $ch_obj->getNode($key2));
echo sprintf("%-50s Map to Node %s\n", $key3, $ch_obj->getNode($key3));
echo sprintf("%-50s Map to Node %s\n", $key4, $ch_obj->getNode($key4));
echo sprintf("%-50s Map to Node %s\n", $key5, $ch_obj->getNode($key5));
echo sprintf("%-50s Map to Node %s\n", $key6, $ch_obj->getNode($key6));
// +----------------------------------------------------------------------
// | View ring and node information
// +----------------------------------------------------------------------
// var_dump($ch_obj->getRing());
// var_dump($ch_obj->nodes);
// +----------------------------------------------------------------------
// | Object for a specific node KEY
// +----------------------------------------------------------------------
// $key1 = $ch_obj->getKey('node_1', 'pre_');
// var_dump($key1);
// +----------------------------------------------------------------------
// | Test distribution
// +----------------------------------------------------------------------
// $keys = array();
// $rings = array();
// for ($i = 1; $i <= 60000; $i++) {
// $key = sha1(rand(1000000,9999999));
// $node = $ch_obj->getNode($key);
// $rings[$node] = isset($rings[$node]) ? ++$rings[$node] : 1;
// }
// var_dump($rings);
Run results:
asofiwjamfdalksjfkasasdflasfja Map to Node node_1
jaksldfjlasfjsdjfioafaslkjflsadkjfl Map to Node node_2
asjldflkjasfsdjflkajkldsjfksajdlflajs Map to Node node_1
iowanfasijfmasdnfoas Map to Node node_2
pqkisndfhoalnfiewlkl Map to Node node_3
qjklasjdifoajfalsjflsa Map to Node node_5
PS: Here are two online tools related to hash for your reference:
Online hash/hash algorithm encryption tool:
http://tools.ofstack.com/password/hash_encrypt
Online MD5/hash/SHA-1/SHA-2/SHA-256/SHA-512/SHA-3/RIPEMD-160 Encryption Tool:
http://tools.ofstack.com/password/hash_md5_sha
For more readers interested in PHP related contents, please check the special topics of this site: "Summary of php Encryption Methods", "Summary of PHP Encoding and Transcoding Operation Skills", "Summary of PHP Mathematical Operation Skills", "Encyclopedia of PHP Array (Array) Operation Skills", "Summary of php String (string) Usage", "Tutorial of PHP Data Structure and Algorithm", "Summary of php Programming Algorithm" and "Summary of php Regular Expression Usage"
I hope this article is helpful to everyone's PHP programming.