http://www.zsythink.net/archives/1182(这个白话文解释挺好没发转载)
hash(i) = hash(i-1) * 33 + str[i]
<?php
function myHash($str) {
// hash(i) = hash(i-1) * 33 + str[i]
$hash = 0;
$s = md5($str);
$seed = 5;
$len = 32;
for ($i = 0; $i < $len; $i++) {
// (hash << 5) + hash 相当于 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;
}
echo myHash("test"); //输出 786776064
<?php
function myHash($str) {
// hash(i) = hash(i-1) * 33 + str[i]
$hash = 0;
$s = md5($str);
$seed = 5;
$len = 32;
for ($i = 0; $i < $len; $i++) {
// (hash << 5) + hash 相当于 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;
}
echo "key1: " . (myHash("key1") % 2) . "\n";
echo "key2: " . (myHash("key2") % 2) . "\n";
<?php
function myHash($str) {
// hash(i) = hash(i-1) * 33 + str[i]
$hash = 0;
$s = md5($str);
$seed = 5;
$len = 32;
for ($i = 0; $i < $len; $i++) {
// (hash << 5) + hash 相当于 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;
}
//echo myHash("却道天凉好个秋~");
echo "key1: " . myHash("key1") . "\n";
echo "key2: " . myHash("key2") . "\n";
echo "key3: " . myHash("key3") . "\n";
echo "serv1: " . myHash("server1") . "\n";
echo "serv2: " . myHash("server2") . "\n";
<?php
function myHash($str) {
// hash(i) = hash(i-1) * 33 + str[i]
$hash = 0;
$s = md5($str);
$seed = 5;
$len = 32;
for ($i = 0; $i < $len; $i++) {
// (hash << 5) + hash 相当于 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;
}
class ConsistentHash {
// server列表
private $_server_list = array();
// 延迟排序,因为可能会执行多次addServer
private $_layze_sorted = FALSE;
public function addServer($server) {
$hash = myHash($server);
$this->_layze_sorted = FALSE;
if (!isset($this->_server_list[$hash])) {
$this->_server_list[$hash] = $server;
}
return $this;
}
public function find($key) {
// 排序
if (!$this->_layze_sorted) {
asort($this->_server_list);
$this->_layze_sorted = TRUE;
}
$hash = myHash($key);
$len = sizeof($this->_server_list);
if ($len == 0) {
return FALSE;
}
$keys = array_keys($this->_server_list);
$values = array_values($this->_server_list);
// 如果不在区间内,则返回最后一个server
if ($hash <= $keys[0] || $hash >= $keys[$len - 1]) {
return $values[$len - 1];
}
foreach ($keys as $key=>$pos) {
$next_pos = NULL;
if (isset($keys[$key + 1]))
{
$next_pos = $keys[$key + 1];
}
if (is_null($next_pos)) {
return $values[$key];
}
// 区间判断
if ($hash >= $pos && $hash <= $next_pos) {
return $values[$key];
}
}
}
}
$consisHash = new ConsistentHash();
$consisHash->addServer("serv1")->addServer("serv2")->addServer("server3");
echo "key1 at " . $consisHash->find("key1") . ".\n";
echo "key2 at " . $consisHash->find("key2") . ".\n";
echo "key3 at " . $consisHash->find("key3") . ".\n";
[php] view plain copy
print?
$ php -f test.php
key1 at server3.
key2 at server3.
key3 at serv2.
原文:https://www.cnblogs.com/aoxueshou/p/9517249.html