Python 的hash 函数

yumo6661周前 (05-16)技术文章4

今天在看python的hash 函数源码的时候,发现针对不同的数据类型python 实现了不同的hash 函数,今天简单介绍源码中提到的hash 函数。(
https://github.com/python/cpython/blob/main/Python/pyhash.c)

  1. 针对short string 类型, python 用的是DJBX33A hash

DJBX33A是DJB(Daniel J. Bernstein)哈希函数的一种变体,专门设计用于快速计算和提供良好的分布特性, 我们来看一下DJBX33A

def djbX33A_hash(key):
    hash_value = 5381  # 初始哈希值

    for char in key:
        hash_value = (hash_value * 33) ^ ord(char)

    return hash_value

同时看一下DJB2 的实现

def djb2_hash(key):
    hash_value = 5381  # Initial hash value

    for char in key:
        hash_value = ((hash_value << 5) + hash_value) + ord(char)
    return hash_value

这个hash 函数用在很多的hashmap 的实现上

  1. 针对文件的hash, python使用的是FNV hash。 我们看一下FNV hash 的具体实现
def fnv_hash(key):
    FNV_PRIME_32 = 16777619
    FNV_OFFSET_32 = 2166136261

    hash_value = FNV_OFFSET_32

    for char in key:
        hash_value = (hash_value ^ ord(char)) * FNV_PRIME_32

    return hash_value
  1. 最后介绍python 默认的hash SipHash, 上面两种hash 函数都是相对不安全的,我们直接看代码
def siphash(key, message):
    c = 2
    d = 4
    v0 = 0x736f6d6570736575
    v1 = 0x646f72616e646f6d
    v2 = 0x6c7967656e657261
    v3 = 0x7465646279746573

    def rotl(x, b):
        return ((x << b) & 0xffffffffffffffff) | (x >> (64 - b))

    def sip_round():
        v0 += v1
        v1 = rotl(v1, 13)
        v1 ^= v0
        v0 = rotl(v0, 32)

        v2 += v3
        v3 = rotl(v3, 16)
        v3 ^= v2

        v0 += v3
        v3 = rotl(v3, 21)
        v3 ^= v0

        v2 += v1
        v1 = rotl(v1, 17)
        v1 ^= v2
        v2 = rotl(v2, 32)

    k0 = int.from_bytes(key[:8], 'little')
    k1 = int.from_bytes(key[8:16], 'little')

    m = len(message)
    last_chunk = m % 8
    b = m // 8 * 8

    v3 ^= k1
    v2 ^= k0
    v1 ^= k1
    v0 ^= k0

    for i in range(b // 8):
        mi = int.from_bytes(message[i*8:(i+1)*8], 'little')
        v3 ^= mi
        for _ in range(d):
            sip_round()
        v0 ^= mi

    mi = (last_chunk << 56) | int.from_bytes(message[b:], 'little')
    v3 ^= mi
    for _ in range(d):
        sip_round()
    v0 ^= mi

    v2 ^= 0xff

    for _ in range(c):
        sip_round()

    hash_value = v0 ^ v1 ^ v2 ^ v3

    return hash_value

最后我们给出python的PEP 456 – Secure and interchangeable hash algorithm | peps.python.orgFollowing system colour schemeSelected dark colour schemeSelected light colour scheme,这篇PEP可以很好的了解的python关于hash的具体事现,以及python的开发者是如何从众多的hash 函数中选择最优的hash function。

相关文章

DAY4-step5 Python示例说明 round()函数

Round()Round()是python提供的内置函数。 它将返回一个浮点数,该浮点数将四舍五入到指定的精度。如果未指定要舍入的小数位,则将其视为0,并将舍入到最接近的整数。语法:round(flo...

Python常用函数整理

以下是Python中常用函数整理,涵盖内置函数、标准库及常用操作,按类别分类并附带示例说明:一、基础内置函数print()输出内容到控制台。pythonprint("Hello, World!...

Python语言的12个基础知识点小结

python编程中常用的12种基础知识总结:正则表达式替换,遍历目录方法,列表按列排序、去重、字典排序、字典、列表、字符串互转,时间对象操作,命令行参数解析(getopt),print 格式化输出,进...

Python 中限制浮点数为两位小数的方法

在 Python 编程里,我们常常会碰到需要把浮点数限制为两位小数的情况。无论是处理财务数据,还是输出需要特定精度的结果,掌握相关方法都很有必要。下面就为大家详细介绍几种实现这一目标的方法。方法一:使...

python基础函数

Python 函数是代码复用的核心工具,掌握基础函数的使用是编程的关键。以下是 Python 函数的系统总结,包含 内置函数 和 自定义函数 的详细用法,以及实际应用场景。一、Python 内置函数(...

Python第十节—常用的内置函数

Pyhton中有一些内置的常用函数,如果每个函数都需要大家定义,那么会很浪费时间,所有今天给大家讲一些Python中的一些内置函数,先讲一讲常用的数学函数取绝对值abs()取长度len()取最大值ma...