首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >哪种字符串哈希算法产生32位或64位有符号整数?

哪种字符串哈希算法产生32位或64位有符号整数?
EN

Stack Overflow用户
提问于 2017-07-24 11:35:53
回答 3查看 2.6K关注 0票数 2

为了节省PostgreSQL中的磁盘空间,我希望将可变长度(6-60个字符长)的字符串散列到32位的PostgreSQL。

我不想加密任何数据,哈希函数需要是可复制的,并且可以从Python调用。问题是,我只能找到生成无符号整数(如CityHash)的算法,从而产生高达2^32的值,而不是2^31。

到目前为止,这就是我所拥有的:

代码语言:javascript
复制
import math
from cityhash import CityHash32

string_ = "ALPDAKQKWTGDR"
hashed_string = CityHash32(string_)
print(hashed_string, len(str(hashed_string)))
max_ = int(math.pow(2, 31) - 1)
print(hashed_string > max_)
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2017-07-25 18:13:04

瑞安在评论中回答了这个问题。从散列结果中减去2147483648 (= 2^31)即可。

代码语言:javascript
复制
CityHash32(string_) - math.pow(2, 31)

代码语言:javascript
复制
CityHash64(string_) - math.pow(2, 63)

Ryan还提到,使用SHA-512并将结果截断到所需的数字数将导致比上述方法更少的冲突。

票数 2
EN

Stack Overflow用户

发布于 2017-07-24 12:27:49

代码语言:javascript
复制
create or replace function int_hash(s text)
returns int as $$

    select ('x' || left(md5(s), 8))::bit(32)::int
    ;
$$ language sql immutable;

select int_hash('1');
  int_hash  
------------
 -993377736
票数 0
EN

Stack Overflow用户

发布于 2019-03-30 17:15:32

我通常不会使用32位散列,除非基数很低,因为它当然比64位散列更有可能发生碰撞。数据库很容易支持双字节8字节(64位)整数.考虑一些哈希冲突概率的这张桌子

如果使用Pythons3.6,则绝对不需要为此使用第三方包,也不需要减去偏移量,因为您可以使用shake_128直接生成带符号的64位或 可变位长散列

代码语言:javascript
复制
import hashlib
from typing import Dict, List


class Int8Hash:

    BYTES = 8
    BITS = BYTES * 8
    BITS_MINUS1 = BITS - 1
    MIN = -(2**BITS_MINUS1)
    MAX = 2**BITS_MINUS1 - 1

    @classmethod
    def as_dict(cls, texts: List[str]) -> Dict[int, str]:
        return {cls.as_int(text): text for text in texts}  # Intentionally reversed.

    @classmethod
    def as_int(cls, text: str) -> int:
        seed = text.encode()
        hash_digest = hashlib.shake_128(seed).digest(cls.BYTES)
        hash_int = int.from_bytes(hash_digest, byteorder='big', signed=True)
        assert cls.MIN <= hash_int <= cls.MAX
        return hash_int

    @classmethod
    def as_list(cls, texts: List[str]) -> List[int]:
        return [cls.as_int(text) for text in texts]

用法:

代码语言:javascript
复制
>>> Int8Hash.as_int('abc')
6377388639837011804
>>> Int8Hash.as_int('xyz')
-1670574255735062145

>>> Int8Hash.as_list(['p', 'q'])
[-539261407052670282, -8666947431442270955]
>>> Int8Hash.as_dict(['i', 'j'])
{8695440610821005873: 'i', 6981288559557589494: 'j'}

若要生成32位哈希,请将Int8Hash.BYTES设置为4。

免责声明:我没有编写统计单元测试来验证这个实现是否返回均匀分布的整数。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45279590

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档