0

0

C++怎么实现一个MurmurHash算法_C++非加密哈希函数与性能分析

尼克

尼克

发布时间:2025-12-04 10:27:07

|

389人浏览过

|

来源于php中文网

原创

MurmurHash3 是高性能非加密哈希函数,适用于 C++ 中哈希表等场景,具有优良分布性与运算速度。

c++怎么实现一个murmurhash算法_c++非加密哈希函数与性能分析

要实现一个高效的非加密哈希函数,MurmurHash 是广泛使用的选择之一,尤其在 C++ 高性能场景中(如哈希表、布隆过滤器等)表现优异。它由 Austin Appleby 在 2008 年提出,具有良好的分布性与极快的运算速度。下面介绍如何在 C++ 中实现 MurmurHash3 的核心算法,并简要分析其性能特点。

MurmurHash3 算法原理

MurmurHash3 是 MurmurHash 系列中最成熟的一个版本,支持 32 位和 128 位输出。它采用混合乘法、异或和移位操作来打乱输入数据的比特分布,核心思想是:

  • 将输入数据按固定字节大小(通常是 4 字节或 16 字节)分块处理
  • 每一块通过一系列“mix”操作更新哈希状态
  • 剩余不足块大小的数据单独处理
  • 最后进行一次终态混合(fmix)以增强雪崩效应

该算法不用于加密安全场景,但对普通哈希用途(如 unordered_map)非常高效。

C++ 实现 MurmurHash3_32

以下是一个简洁的 MurmurHash3 32 位版本实现,适用于任意长度的字节数组:

立即学习C++免费学习笔记(深入)”;

#include 
#include 

// 常量定义 static constexpr uint32_t MURMUR_SEED = 0xc70f6907; // 可自定义种子 static constexpr uint32_t c1 = 0xcc9e2d51; static constexpr uint32_t c2 = 0x1b873593;

uint32_t murmur3_32(const uint8_t* key, size_t len) { uint32_t h = MURMUR_SEED; uint32_t k;

const uint8_t* tail;
const uint32_t* blocks = reinterpret_castzuojiankuohaophpcnconst uint32_t*youjiankuohaophpcn(key);

// 处理完整的 4 字节块
for (size_t i = len / 4; i != 0; i--) {
    k = *blocks++;
    k *= c1;
    k = (k zuojiankuohaophpcnzuojiankuohaophpcn 15) | (k youjiankuohaophpcnyoujiankuohaophpcn 17);
    k *= c2;

    h ^= k;
    h = (h zuojiankuohaophpcnzuojiankuohaophpcn 13) | (h youjiankuohaophpcnyoujiankuohaophpcn 19);
    h = h * 5 + 0xe6546b64;
}

// 处理剩余字节(0~3 字节)
tail = reinterpret_castzuojiankuohaophpcnconst uint8_t*youjiankuohaophpcn(blocks);
k = 0;
switch (len & 3) {
    case 3: k ^= tail[2] zuojiankuohaophpcnzuojiankuohaophpcn 16;
    case 2: k ^= tail[1] zuojiankuohaophpcnzuojiankuohaophpcn 8;
    case 1: k ^= tail[0];
            k *= c1;
            k = (k zuojiankuohaophpcnzuojiankuohaophpcn 15) | (k youjiankuohaophpcnyoujiankuohaophpcn 17);
            k *= c2;
            h ^= k;
};

// 终态混合
h ^= len;
h ^= h youjiankuohaophpcnyoujiankuohaophpcn 16;
h *= 0x85ebca6b;
h ^= h youjiankuohaophpcnyoujiankuohaophpcn 13;
h *= 0xc2b2ae35;
h ^= h youjiankuohaophpcnyoujiankuohaophpcn 16;

return h;

}

这个实现可以直接用于字符串或内存块:

ChartCube
ChartCube

图标魔方 - 在线图表制作工具

下载
#include 
#include 

int main() { std::string str = "hello world"; uint32_t hash = murmur3_32( reinterpret_cast(str.data()), str.size() ); std::cout << "Hash: " << hash << "\n"; return 0; }

性能优势与适用场景

MurmurHash3 在现代 CPU 上表现出色,主要得益于:

  • 高吞吐量:利用了 CPU 的并行执行能力,指令间依赖少
  • 良好分布:在大量测试集中表现出优秀的雪崩效应和碰撞率
  • 无分支预测惩罚:主循环几乎无条件跳转,适合流水线执行
  • 跨平台兼容:不依赖特定字节序(小端优先),可移植性强

相比于 std::hash 或 DJB2 等传统哈希函数,MurmurHash3 在长字符串和结构体哈希中更稳定,常被用于:

  • 高性能哈希容器(如自定义 unordered_set)
  • 分布式系统中的 consistent hashing
  • 数据库索引键哈希
  • 缓存键生成

在实际 benchmark 中,MurmurHash3 的速度通常优于 CityHash 和 SpookyHash,尤其在中短文本上优势明显。

注意事项与优化建议

使用时需注意几点:

  • 种子值影响哈希结果,多线程环境中若需一致性应固定种子
  • 对极短字符串(如 1~4 字节),部分混合可省略以进一步提速
  • 若追求极致性能,可使用 MurmurHash3 的 SIMD 优化版本(如 x86 AVX)
  • 不要用于安全敏感场景(如密码存储、防篡改)

可以将其封装为模板函数,适配 std::string、char[]、std::array 等常见类型,提升易用性。

基本上就这些。MurmurHash 是非加密哈希中的“瑞士军刀”,实现简单、速度快、效果好,值得在性能敏感项目中优先考虑。

相关文章

数码产品性能查询
数码产品性能查询

该软件包括了市面上所有手机CPU,手机跑分情况,电脑CPU,电脑产品信息等等,方便需要大家查阅数码产品最新情况,了解产品特性,能够进行对比选择最具性价比的商品。

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
什么是分布式
什么是分布式

分布式是一种计算和数据处理的方式,将计算任务或数据分散到多个计算机或节点中进行处理。本专题为大家提供分布式相关的文章、下载、课程内容,供大家免费下载体验。

325

2023.08.11

分布式和微服务的区别
分布式和微服务的区别

分布式和微服务的区别在定义和概念、设计思想、粒度和复杂性、服务边界和自治性、技术栈和部署方式等。本专题为大家提供分布式和微服务相关的文章、下载、课程内容,供大家免费下载体验。

232

2023.10.07

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

318

2023.08.02

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

258

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

208

2023.09.04

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1465

2023.10.24

字符串介绍
字符串介绍

字符串是一种数据类型,它可以是任何文本,包括字母、数字、符号等。字符串可以由不同的字符组成,例如空格、标点符号、数字等。在编程中,字符串通常用引号括起来,如单引号、双引号或反引号。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

620

2023.11.24

java读取文件转成字符串的方法
java读取文件转成字符串的方法

Java8引入了新的文件I/O API,使用java.nio.file.Files类读取文件内容更加方便。对于较旧版本的Java,可以使用java.io.FileReader和java.io.BufferedReader来读取文件。在这些方法中,你需要将文件路径替换为你的实际文件路径,并且可能需要处理可能的IOException异常。想了解更多java的相关内容,可以阅读本专题下面的文章。

550

2024.03.22

PHP WebSocket 实时通信开发
PHP WebSocket 实时通信开发

本专题系统讲解 PHP 在实时通信与长连接场景中的应用实践,涵盖 WebSocket 协议原理、服务端连接管理、消息推送机制、心跳检测、断线重连以及与前端的实时交互实现。通过聊天系统、实时通知等案例,帮助开发者掌握 使用 PHP 构建实时通信与推送服务的完整开发流程,适用于即时消息与高互动性应用场景。

3

2026.01.19

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Java 教程
Java 教程

共578课时 | 47.8万人学习

国外Web开发全栈课程全集
国外Web开发全栈课程全集

共12课时 | 1.0万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号