RocksDB 解密可逆哈希:BijectiveHash的设计奥秘

BijectiveHash(双射哈希,即可逆哈希)的设计精髓在于它借鉴了现代密码学和高性能哈希函数中的核心思想,但目标并非加密,而是实现一种无冲突、可逆的置换(Permutation)

可逆哈希是什么,用来做什么?

首先要明确,它和我们通常说的用于哈希表或数据校验的哈希函数(如 Hash64)完全不同。

  • 普通哈希:是多对一的,输入空间远大于输出空间,必然存在冲突(多个不同输入产生相同输出),并且是单向的(不可逆)。
  • 可逆哈希:是一对一的,输入和输出空间大小相同,绝无冲突,并且是双向的(可逆的)。

它的主要用途是数据混淆(Obfuscation)ID置换。比如,你有一组从0开始连续的ID(0, 1, 2, ...),但你不想直接暴露它们,希望把它们变成一组看起来毫无规律、随机分布的ID,同时还能在需要时恢复成原始ID。这时可逆哈希就派上用场了。

BijectiveHash2x64 设计精髓分析

这个函数的设计巧妙地改编自 XXH3 哈希算法中处理小数据块的部分。XXH3为了达到雪崩效应,混合极其充分,而BijectiveHash则利用了这种充分混合的特性,并确保每一步操作都是可逆的。

我们来看它的核心代码:

hash.cc

// ... existing code ...
void BijectiveHash2x64(uint64_t in_high64, uint64_t in_low64, uint64_t seed,uint64_t* out_high64, uint64_t* out_low64) {// Adapted from XXH3_len_9to16_128bconst uint64_t bitflipl = /*secret part*/ 0x59973f0033362349U - seed;const uint64_t bitfliph = /*secret part*/ 0xc202797692d63d58U + seed;Unsigned128 tmp128 =Multiply64to128(in_low64 ^ in_high64 ^ bitflipl, 0x9E3779B185EBCA87U);uint64_t lo = Lower64of128(tmp128);uint64_t hi = Upper64of128(tmp128);lo += 0x3c0000000000000U;  // (len - 1) << 54in_high64 ^= bitfliph;hi += in_high64 + (Lower32of64(in_high64) * uint64_t{0x85EBCA76});lo ^= EndianSwapValue(hi);tmp128 = Multiply64to128(lo, 0xC2B2AE3D27D4EB4FU);lo = Lower64of128(tmp128);hi = Upper64of128(tmp128) + (hi * 0xC2B2AE3D27D4EB4FU);*out_low64 = XXH3_avalanche(lo);*out_high64 = XXH3_avalanche(hi);
}
// ... existing code ...
设计精髓 1:保证无信息丢失的操作

要实现可逆,最关键的一点是任何操作都不能丢失信息

  • Multiply64to128:这是整个设计的核心。普通的64位乘法 uint64_t * uint64_t 的结果仍然是 uint64_t,这会丢失高64位的信息,导致不可逆。而 Multiply64to128 将两个64位整数相乘,产生一个完整的128位结果(Unsigned128),完整保留了所有信息。这是可逆性的数学基础。
  • XOR (^) 和加法 (+):这些操作本身就是可逆的。a ^ b 可以通过再异或一次 b 恢复 aa + b 可以通过减去 b 恢复 a
设计精髓 2:借鉴密码学的“混淆”与“扩散”

为了让输出看起来随机,它借鉴了密码学中的两个重要概念:

  • 混淆(Confusion):让输入和输出之间的关系变得尽可能复杂。
    • 通过与seed相关的密钥(bitfliplbitfliph)进行XOR操作。
    • 与大的素数(0x9E3779B185EBCA87U 等)相乘。
  • 扩散(Diffusion):让输入的任何一位微小变化都能影响到输出的多位(雪崩效应)。
    • lo ^= EndianSwapValue(hi):这是一个类似Feistel网络的结构。它用一部分数据(hi)去改变另一部分数据(lo),然后再用改变后的lo去影响hi的计算。这种交叉影响能迅速地将输入的变化扩散到整个128位状态中。
    • XXH3_avalanche:最后调用XXH3的雪崩函数,进行最终的、彻底的混合,确保最终输出的随机性。
设计精髓 3:可逆的雪崩函数

XXH3_avalanche 本身是一个单向函数,但设计者巧妙地为它实现了一个逆函数 XXH3_unavalanche

// ... existing code ...
inline uint64_t XXH3_avalanche(uint64_t h64) {h64 ^= h64 >> 37;h64 *= 0x165667919E3779F9U;h64 ^= h64 >> 32;return h64;
}inline uint64_t XXH3_unavalanche(uint64_t h64) {h64 ^= h64 >> 32;h64 *= 0x8da8ee41d6df849U;  // inverse of 0x165667919E3779F9Uh64 ^= h64 >> 37;return h64;
}
// ... existing code ...

这里的关键是 0x8da8ee41d6df849U,它是 0x165667919E3779F9U 在模 2^64 意义下的乘法逆元。这意味着 (a * b) * b_inverse = a (mod 2^64)。通过找到这个逆元,乘法步骤就变得可逆了。而XOR和移位操作的逆运算也相对直接。

BijectiveUnhash2x64:逆向工程的艺术

逆向函数 BijectiveUnhash2x64 的实现完美展示了如何一步步“撤销”正向函数的操作。

// ... existing code ...
void BijectiveUnhash2x64(uint64_t in_high64, uint64_t in_low64, uint64_t seed,uint64_t* out_high64, uint64_t* out_low64) {// Inverted above (also consulting XXH3_len_9to16_128b)const uint64_t bitflipl = /*secret part*/ 0x59973f0033362349U - seed;const uint64_t bitfliph = /*secret part*/ 0xc202797692d63d58U + seed;uint64_t lo = XXH3_unavalanche(in_low64);uint64_t hi = XXH3_unavalanche(in_high64);// ... a series of inverse multiplications, subtractions, and XORs ...// ... in the exact reverse order of the forward function ...*out_high64 = hi;*out_low64 = lo;
}
// ... existing code ...

它的每一步都精确地对应 BijectiveHash2x64 的逆操作,并严格按照相反的顺序执行:

  1. 先用 XXH3_unavalanche 撤销雪崩混合。
  2. 用乘法逆元撤销乘法。
  3. 用减法撤销加法。
  4. 用XOR撤销XOR。

总结:设计精髓

  1. 以无损操作为基石:使用扩展精度运算(如64->128位乘法)来确保计算过程不丢失任何信息,这是可逆性的前提。
  2. 借鉴密码学思想:采用Feistel网络、密钥(seed)混淆、乘大素数等方式实现充分的混淆和扩散,让输出看起来随机。
  3. 依赖数论工具:可逆性的实现严重依赖于数论,特别是模乘法逆元的计算,这是将单向乘法变为双向的关键。
  4. 结构对称:正向和逆向过程在结构上是完全对称的,逆向过程是正向过程的完美“镜像”。

通过学习这个设计,我们可以看到一个看似简单的“可逆哈希”背后,融合了计算机体系结构(扩展精度乘法)、密码学(混淆扩散)和数论(模逆元)的深刻原理,是高性能计算和算法设计的典范。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/919270.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/919270.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

05.用户和组管理命令

用户和组管理命令用户和组管理命令1. getent2. useradd3. usermod4. userdel5. id6. su7. passwd8. chage9. groupadd10. groupmod11. groupdel12. gpasswd13. groupmems用户和组管理命令 用户和组的主要配置文件 /etc/passwd&#xff1a;用户及其属性信息(名称、UID、主组ID…

go 多版本共存【goup + alias方案】

一、需求背景 以go1.21为主&#xff0c;临时可以快速切换到go1.23,且只有当前窗口生效 二、安装 安装 goup go install github.com/owenthereal/goup/cmd/gouplatest安装 go1.23 # 注意这里是安装新的sdk,如果你本地存在相同版本的话&#xff0c;应该保持统一用goup安装的 goup…

DR200差速移动机器人的多功能感知系统与多场景应用

DR200差速移动机器人平台是一款基于室内平地的差速转向移动机器人底盘&#xff0c;主要针对教育教学、超市移动促销、无人配送、室内仓储、室内巡检、物流搬运等行业。整套底盘采用了4个万向轮和双驱动轮差速驱动结构&#xff0c;间驱动轮带直流无刷伺服电机。整套结构采用了摆…

基于ZLMediaKit的大疆上云视频流服务集成方案

引言 随着无人机技术的快速发展&#xff0c;大疆&#xff08;DJI&#xff09;设备产生的高清视频流需要高效、低延迟的云端处理方案。传统基于SRS的视频流服务在多协议支持和并发性能上存在局限&#xff0c;而ZLMediaKit作为一款高性能流媒体服务框架&#xff0c;凭借其多协议支…

用 Python 实现一个“小型 ReAct 智能体”:思维链 + 工具调用 + 环境交互

在大语言模型&#xff08;LLM&#xff09;的应用开发中&#xff0c;如何让模型具备调用外部工具的能力是一个关键问题。我们不希望模型只是“生成答案”&#xff0c;而是能像一个智能体&#xff08;Agent&#xff09;一样&#xff0c;按照推理链条自主决定调用搜索、计算、或数…

集成电路学习:什么是SIFT尺度不变特征变换

SIFT:尺度不变特征变换 SIFT(尺度不变特征变换,Scale Invariant Feature Transform)是一种在图像处理和计算机视觉领域广泛应用的算法,由David Lowe在1999年提出。该算法能够在图像的不同尺度、旋转和光照条件下保持特征不变性,从而提取出独特的特征点,并用于图像…

短视频流量|基于Java+vue的短视频流量数据分析系统(源码+数据库+文档)

短视频流量数据分析系统 基于SprinBootvue的短视频流量数据分析系统 一、前言 二、系统设计 三、系统功能设计 系统功能模块 管理员功能模块实现 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取&#xff1a; 博主介绍&#xff…

【无标题】卷轴屏手机前瞻:三星/京东方柔性屏耐久性测试进展

卷轴屏手机前瞻&#xff1a;三星/京东方柔性屏耐久性测试进展卷轴屏手机的产业化突破临近2025年全球柔性屏市场规模预计突破186亿美元&#xff0c;其中卷轴屏技术正从概念走向量产。三星显示近期宣布新一代柔性OLED面板通过50万次折叠认证&#xff0c;日均折叠200次可使用6年以…

Git 入门指南:核心概念与常用命令全解析

Git 入门指南&#xff1a;核心概念与常用命令全解析前言一、Git相关概念1.1 工作目录1.2 暂存区1.3 本地仓库1.3 远程仓库1.3.1 首次提交到远程仓库提示输入用户名密码1.3.2 解决方法二、Git常用命令2.1 配置命令2.1.1 查看当前 Git 配置的所有信息2.1.2 查看系统全局配置2.1.3…

悬赏任务网站源码多平台兼职赚钱搭建图解

功能详细说明 &#xff08;一&#xff09;登录与注册 1、登录&#xff1a;打开系统用户端&#xff0c;输入已注册的手机号和密码进行登录。 若为忘记密码&#xff0c;可通过 “找回密码” 功能&#xff0c;按提示验证身份后重置密码登录。 2、注册&#xff1a;点击 “注册” 按…

Node.js简介及安装

一、Nodejs简介 1、核心定义 Node.js 是一个基于 Chrome V8 引擎的开源、跨平台 JavaScript 运行时环境&#xff08;Runtime&#xff09;&#xff0c;用于在服务器端或本地运行 JavaScript 代码。它并非编程语言、库或框架&#xff0c;而是扩展了 JavaScript 的能力&#xff0…

KINGBASE集群日常维护管理命令总结

查看集群的状态 [kingbasenode1 bin]$ repmgr cluster show查看守护集群状态 [kingbasenode1 bin]$ repmgr service status查看集群的事件 [kingbasenode1 etc]$ repmgr cluster event查看集群流复制状态 esrep#select usename,application_name,client_addr,sync_state,state,…

GoLand 调参高手都在用的配置!续集:WebStorm 飞升后,Go 开发 IDE 性能炸裂的秘密

“为什么别人的 GoLand 运行 Go 项目丝滑流畅&#xff0c;而你的却频繁卡顿、编译转圈&#xff1f;秘密就藏在这个 goland64.exe.vmoptions文件里&#xff01;作为 IDEA/PyCharm/WebStorm 调优系列的续集&#xff0c;我把我压箱底的 ​GoLand 性能调优参数表​ 分享出来—>&…

48Days-Day19 | ISBN号,kotori和迷宫,矩阵最长递增路径

ISBN号 ISBN号码_牛客题霸_牛客网 算法原理 模拟&#xff0c;根据题意模拟就可以了&#xff0c;注意一下余数为10的时候要特别判断一下是不是X就行了 代码 import java.util.Scanner;// 注意类名必须为 Main, 不要有任何 package xxx 信息 public class Main {public stat…

Java 泛型类型擦除

&#x1f4d6; 概述 本文档详细解释了 Flink 中 TypeInformation 的作用、原理和使用方法&#xff0c;帮助理解为什么 Flink 需要显式的类型信息。 &#x1f3af; 核心问题&#xff1a;Java 泛型类型擦除 什么是类型擦除&#xff1f; Java 在编译时会将泛型信息擦除&#xff0c…

从“写代码”到“定义需求”:AI编程工具如何重构软件开发的核心流程?

从“写代码”到“定义需求”&#xff1a;AI编程工具如何重构软件开发的核心流程&#xff1f; 软件开发的核心流程正在经历一场静默革命。十年前&#xff0c;开发者的日常被“写代码”填满——从变量定义到逻辑实现&#xff0c;每行代码都需要手动敲击&#xff1b;而今天&#x…

一颗TTS语音芯片给产品增加智能语音播报能力

​一颗TTS语音芯片给产品增加智能语音播报能力传统语音播报芯片可以设置一些固定的语音片段或者内容&#xff0c;但是对于现在各种创新产品层出不穷的时代&#xff0c;传统的语音播报芯片能力似乎有点不够用了。而TTS语音合成芯片&#xff0c;正在逐渐登上舞台中央。TTS语音合成…

[免费]基于Python的影视数据可视化分析系统(Flask+echarts)【论文+源码+SQL脚本】

大家好&#xff0c;我是python222_小锋老师&#xff0c;看到一个不错的基于Python的影视数据可视化分析系统(Flaskecharts)&#xff0c;分享下哈。 项目视频演示 【免费】基于Python的爱奇艺影视电影数据可视化分析系统(Flaskecharts) Python毕业设计_哔哩哔哩_bilibili 系统…

Three.js 材质系统深度解析

简介 Three.js 是一个功能强大的开源 3D 图形库&#xff0c;广泛应用于 Web 端的 3D 可视化开发。其材质系统是 Three.js 的核心组成部分之一&#xff0c;负责定义 3D 对象的表面外观和渲染效果。从简单的颜色填充到复杂的动态效果&#xff0c;材质系统为开发者提供了高度灵活…

FP16(半精度)和FP32(单精度)

FP16&#xff08;Half-Precision Floating Point&#xff0c;半精度浮点数&#xff09;是一种使用16位二进制数表示浮点数值的数据格式&#xff0c;在深度学习、图形渲染和高性能计算中广泛应用。其核心定义、技术特性与应用价值如下&#xff1a;一、FP16的核心定义与结构二进制…