Python 的hash 函数

yumo6664个月前 (05-16)技术文章60

今天在看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。

相关文章

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

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

全国计算机等级考试二级Python易错真题详解-流程控制-单选题

流程控制(单选题)说明:本文中的题目,全都来自全国计算机等级考试二级Python语言程序设计考试的真题,且都为易错题。题干最后如有编号,则是 python123 平台上的题号,以方便学生查找和索引。在...

8-Python内置函数

Python 提供了丰富的内置函数,这些函数可以直接使用而无需导入任何模块。以下是一些常用的内置函数及其示例:1-print()1-1-说明输出指定的信息到控制台。1-2-例子2-len()2-1-说...

Python 最常用的语句、函数有哪些?

1. #coding=utf-8① 代码中有中文字符,最好在代码前面加#coding=utf-8② pycharm不加可能不会报错,但是代码最终是会放到服务器上,放到服务器上的时候运行可能会报错。③...

Python 内置函数速查手册(函数大全,带示例)

1. abs()abs() 返回数字的绝对值。>>> abs(-7)输出: 7>>> abs(7)输出:72. all()all() 将容器作为参数。如果 pyth...