为哈希生成唯一得分的最佳方法是什么?

时间:2016-01-06 15:19:20

标签: python hash

我正在尝试编写代码,以便为每个哈希生成唯一的分数。基本上我想要将同一节点返回给多个用户,如果他们请求相同的内容。

这是我的代码:

import hashlib
#define nodes
nodes = ["192.168.20.2", "192.168.20.3", "192.168.20.4", "192.168.20.5", "192.168.20.6", "192.168.20.7"]

def selectNodes(clientIP,request):
    hash_list = []
 for node_ips in nodes:
        score = 0
        ready_hash = str(request) + str(node_ips)
        m = hashlib.md5((ready_hash).encode("utf-8"))
        hashed_node = m.hexdigest()
        for char in hashed_node:
            score += int(char, 16)
        hash_list.append((node_ips, score))
    sorted_by_score = sorted(hash_list, key=lambda tup:tup[1], reverse=True)

    (node_ip, score) = sorted_by_score[0]
    return (node_ip, sorted_by_score)

如果我打电话:

selectNodes("10.10.10.20", "movie1")

假设它为movie1返回192.168.20.2。下次当相同或其他用户请求“movie1”时。它应该返回相同的节点192.168.20.2。我不想将{电影映射到节点}。它应该在运行时计算并给出正确的结果。

上面的代码对我来说很好,但有时候节点的计算分数变得相同。

我能做些什么来计算每个哈希的唯一得分。

2 个答案:

答案 0 :(得分:2)

始终将同一节点分配给同一请求的解决方案是仅使用请求的散列索引节点列表(以模块的长度为模)。

#define nodes
nodes = ["192.168.20.2", "192.168.20.3", "192.168.20.4", "192.168.20.5", "192.168.20.6", "192.168.20.7"]

def selectNodes(request):
    return nodes[hash(str(request)) % len(nodes)]

答案 1 :(得分:0)

此解决方案不依赖于节点顺序,但如果将新节点添加到列表中,则可能会更改输出。它使用Murmur3哈希函数。

import mmh3

nodes = [
    "192.168.20.2",
    "192.168.20.3",
    "192.168.20.4",
    "192.168.20.5",
    "192.168.20.6",
    "192.168.20.7",
]

def generate_hash(request, node_ip):
    return mmh3.hash("%s-%s" % (request, node_ip))


def select_node(client_ip, request):
    hashes = [
        [generate_hash(request, node_ip), node_ip]
        for node_ip in nodes
    ]
    return sorted(hashes, reverse=True)[0][-1]  # sorted by hash


print select_node("10.10.10.20", "movie2")
print select_node("10.10.10.10", "movie2")