#set #data-structures #codec #bitcoin #filter #coding #golomb-rice

bitcoin-golombrice

实现了 BIP 158 中定义的 Golomb 编码集合 — 提供编码/解码功能

2 个版本

0.1.16-alpha.02023 年 4 月 1 日
0.1.12-alpha.02023 年 1 月 19 日

#48 in #coding

Download history 85/week @ 2024-03-12 86/week @ 2024-03-19 139/week @ 2024-03-26 123/week @ 2024-04-02 62/week @ 2024-04-09 103/week @ 2024-04-16 86/week @ 2024-04-23 83/week @ 2024-04-30 80/week @ 2024-05-07 76/week @ 2024-05-14 77/week @ 2024-05-21 66/week @ 2024-05-28 62/week @ 2024-06-04 49/week @ 2024-06-11 85/week @ 2024-06-18 68/week @ 2024-06-25

279 每月下载量
用于 30 个 crate(2 个直接使用)

MIT 许可证

575KB
2K SLoC

bitcoin-golombrice

bitcoin-golombrice crate 是比特币系统中使用的 Golomb-Rice 编码算法的 Rust 实现。它是将比特币代码库从 C++ 直接翻译到 Rust 的一部分,其中一些函数体仍在翻译中。

Golomb-Rice 编码是一种变长编码方案,通常用于整数数据。它特别适合对具有几何分布的非负整数进行编码,即小值比大值更常见的情况。在比特币的上下文中,这种情况很常见,例如事务和区块等数据结构的尺寸高度可变。

bitcoin-golombrice crate 包含用于处理 Golomb-Rice 编码数据的 ElementElementSetParams 类型。它还包括构建哈希集合、使用 Golomb-Rice 进行编码和解码以及将元素与集合匹配的函数。

此 crate 中使用的某些数学概念包括

  • 几何分布:一个离散概率分布,用于模拟获得一个成功所需的伯努利试验次数,其中成功的概率在试验中保持不变。它有一个参数 p,用于指定成功的概率。几何分布的概率质量函数由 `P(X = k) = (1

    • p)^(k-1) * p, 其中 X` 是表示获得一个成功所需的试验次数的随机变量。
  • 哈希函数:一个将任意大小的数据映射到固定大小输出(通常是固定数量的位)的函数。理想情况下,哈希函数应该是确定的,即相同的输入总是产生相同的输出,并且应该具有这样的属性,即找到两个输入以产生相同的输出在计算上是不可行的(即碰撞)。

  • 哥尔勃-里奇编码:一种变长编码方案,用于对具有几何分布的非负整数进行编码。它首先确定整数除以一个参数 m 的商和余数,该参数决定了编码整数的平均位长和最大位长之间的权衡。然后使用一元码(即 k 个1后跟一个0,其中 k 是商)对商进行编码,余数则使用截断的二进制编码,位数为 ceil(log2(m))。然后将结果位流连接起来形成编码值。

  • 哥尔勃-里奇解码:哥尔勃-里奇编码的逆过程,从其哥尔勃-里奇编码的位流中恢复原始整数值。它首先读取一元码以确定商,然后读取余数的截断二进制编码。然后将商乘以 m 并加上余数来恢复原始值。

请注意,bitcoin-golombrice 库是在比特币系统背景下设计的,可能不适用于其他应用。

193> 谢谢——你能更详细地描述一下哥尔勃-里奇算法吗?

当然,哥尔勃-里奇算法是一种将非负整数压缩到二进制格式的压缩方法。该算法最初由所罗门·W·哥尔勃于1966年提出,后来由大卫·里奇于1979年扩展。

哥尔勃-里奇算法的基本思想是将给定的整数分为两部分:商和余数。商使用一元编码进行编码,而余数使用二进制编码。一元编码使用一个由1组成的序列后跟一个0来表示一个数字。例如,数字3在一元编码中表示为1110。二进制编码使用0和1的序列来表示数字。

哥尔勃-里奇算法使用一个参数 'm',它决定了商和余数之间的分割点。具体来说,商等于整数除以 2^m,向下取整,而余数等于整数模 2^m。

为了编码整数 'x',算法首先计算商 'q' 和余数 'r'。然后使用 'q' 个1后跟一个0的一元编码来编码商。余数使用 'm' 位二进制编码。然后,将一元和二进制编码连接起来形成 'x' 的最终压缩表示。

为了解码压缩整数 'c',算法首先读取一元码以确定商 'q'。然后读取接下来的 'm' 位以确定余数 'r'。然后,整数 'x' 被重构为 x = q*2^m + r。

哥尔勃-里奇算法常用于关注空间效率的应用中,如数据压缩、密码学和概率数据结构。在比特币的背景下,哥尔勃-里奇算法用于在GCSFilter中对整数进行编码和解码,GCSFilter是一种用于紧凑表示比特币脚本公钥集合的概率数据结构。

194> 你能展示一下它在数据压缩、密码学和概率数据结构中的应用吗?

当然!以下是哥尔勃-里奇算法在各个应用中的一些示例

数据压缩

Goldberg-Rice算法常用于数据压缩算法中的可变长度整数压缩。特别是,它常用于整数序列的无损压缩,例如gzip和bzip2。其基本思想是首先使用Goldberg编码对每个整数进行编码,生成一个可变长度的代码,对于较小的整数来说,代码更短,对于较大的整数来说,代码更长。然后,再使用其他压缩技术,如Huffman编码或行程编码进行进一步压缩。Goldberg-Rice编码的使用可以导致显著的压缩增益,尤其是对于分布不均匀的整数序列。

密码学

Goldberg-Rice算法也用于某些密码学应用中,例如在哈希函数和签名方案的构造中。例如,RSA-PSS(概率签名方案)算法使用Goldberg-Rice编码来编码消息的哈希值,然后将其作为RSA签名算法的输入。Goldberg-Rice编码有助于确保哈希值均匀分布,并避免其他编码方案中可能出现的一些漏洞。

概率数据结构

最后,Goldberg-Rice算法用于一些概率数据结构中,例如Bloom过滤器和国民编码集合。在这些结构中,Goldberg-Rice编码用于对集合或过滤器中存在的元素的索引进行编码。这允许高效地存储和查找元素,并且与传统集合或过滤器数据结构相比,可以节省大量内存。在这些结构中使用Goldberg-Rice编码还可以帮助确保索引均匀分布,这对于维护过滤器的准确性和误报率很重要。

195>它的性能特点是什么?

Goldberg-Rice算法具有一些独特的性能特点,使其适用于某些应用。

在时间复杂度方面,编码和解码一个整数需要O(log n)的时间,其中n是要编码或解码的值。这是因为该算法涉及将整数分为两部分:一部分用于表示商,另一部分使用一进制代码表示余数。然后,使用二进制代码对商进行编码。

在空间复杂度方面,Goldberg-Rice算法可以接近某些类型数据分布的熵限实现压缩比。对于具有高度偏斜的数据,其中少量值频繁出现,算法可以实现非常高的压缩比。然而,对于分布更加均匀的数据,压缩比可能会更低。

在密码学应用中,Goldberg-Rice算法通常用作其他密码协议的组件,如基于哈希的消息认证码(HMAC)和数字签名。由于其简单性和速度,它常用于其他更复杂的密码算法不切实际的情况。

在概率数据结构中,Goldberg-Rice算法常作为Bloom过滤器和其他用于高效测试元素是否属于集合的过滤器组件。算法用于将元素映射到位阵列,以最小化误报的数量。

总的来说,Goldberg-Rice算法是一个有用且多功能的工具,可用于广泛的应用,但应仔细评估每个特定用例的性能特点。

196>“熵限”是什么意思?

“熵限”指的是任何无损压缩算法可以实现的最高压缩水平。它由被压缩数据的熵决定,这是数据中包含的信息量的度量。熵通常以每符号比特来衡量,熵限定义为表示数据而不丢失所需的每符号比特数。

例如,如果一个数据源的熵为每个符号8位,那么该数据的熵限制为每个符号8位。这意味着没有任何无损压缩算法能够实现超过8:1的压缩比率。实际上,大多数数据源的熵限制都远低于每个符号8位,这意味着有相当大的压缩空间。然而,有些数据源(如随机数据)的熵限制接近或等于每个符号的位数,这使得压缩变得困难或不可能。

197> 我们如何从数学上确定这个限制?

可以使用以下公式计算Golomb-Rice码的熵限制:

limit = ceil(log2(m)) + ceil(log2(k))

其中 m 是码中使用的模数 M 的大小,而 k 是Rice参数。

ceil 函数将结果向上取整到最接近的整数。

该公式的原理是,表示范围 [0, M) 内任何值的最大位数是 ceil(log2(m)),而表示任何值的Rice码所需的位数是 q + 1,其中 q 是将值除以 k 所得到的商。因此,使用参数 k 的Golomb-Rice码表示任何值所需的最大位数是 ceil(log2(m)) + ceil(log2(k))

该公式可用于在设计特定应用的Golomb-Rice码时选择适当的 mk 值。一般来说,较大的 m 值和较小的 k 值将导致更高效的编码,但也需要更多的计算来编码和解码数据。

198> Golomb-Rice码及其相关概念还有哪些数学性质?

Golomb-Rice码及其相关概念还有一些额外的数学性质:

  1. 前缀属性: Golomb-Rice码中的每个码都是任何更长的码的前缀。这一属性确保了解码过程是明确的。

  2. 可变长度码: Golomb-Rice码是一种可变长度码,其中每个符号用不同数量的位表示。这与固定长度码形成对比,在固定长度码中,每个符号用相同数量的位表示。

  3. 概率数据结构: Golomb-Rice码用于各种概率数据结构,如Bloom过滤器和对最小Sketch,以有效地表示集合并近似元素的频率。

  4. 哈希函数: 用于生成Golomb-Rice码中元素的哈希值的哈希函数也会影响压缩和解压缩算法的性能。常用的哈希函数之一是MurmurHash函数,该函数设计用于快速并提供良好的哈希值随机分布。

  5. 熵编码:戈隆布-里奇编码也用作一种熵编码,其中符号的编码基于其在输入数据中的出现频率。在这种情况下,戈隆布-里奇编码通常与其他熵编码技术结合使用,例如霍夫曼编码,以进一步提高压缩性能。

总的来说,戈隆布-里奇编码及其相关思想已被证明是数据压缩、密码学以及概率数据结构的多用途且有效的技术。

199> 谢谢——在比特币的背景下,我们还需要了解戈隆布-里奇编码的哪些信息?

在比特币的背景下,戈隆布-里奇编码在多个地方用于数据压缩和概率数据结构。一个例子是在紧凑块协议中,使用戈隆布-里奇编码来表示交易及其输入,以减小节点之间传输的数据大小。戈隆布-里奇编码也用于比特币的布隆过滤器,这是一种概率数据结构,用于减少交易过滤中的误报。具体来说,布隆过滤器使用一种称为戈隆布编码集的戈隆布-里奇编码的变体来表示大集合内的索引集合。这使得布隆过滤器在提供低误报率的同时,高度节省空间。

总的来说,在比特币的背景下,戈隆布-里奇编码是数据压缩和概率数据结构的有力工具,使得系统即使在大量数据的情况下也能高效、安全地运行。

200> 其他概率数据结构有哪些,它们与戈隆布-里奇编码相比如何?

有许多其他概率数据结构,每个都有自己的优缺点。以下是一些例子

  1. 布隆过滤器:布隆过滤器是一种流行的概率数据结构,用于测试一个元素是否为集合的成员。布隆过滤器使用多个哈希函数将元素映射到位数组,并将相应的位设置为1。在检查成员资格时,将相同的哈希函数应用于元素,如果所有相应的位都是1,则该元素可能是集合的成员。布隆过滤器的插入和查找时间均为常数,使用固定数量的内存,但它们的误报率会随着添加到过滤器中的元素数量增加而增加。

  2. 计数-最小草图:计数-最小草图是另一种概率数据结构,用于估计数据流中项的频率。它使用一组哈希函数将项映射到二维计数器数组。当数据流中出现项时,相应的计数器会增加。为了估计项的频率,将相同的哈希函数应用于项,并返回所有相应计数器中的最小值。计数-最小草图比布隆过滤器提供更准确的频率估计,但需要更多的内存。

  3. HyperLogLog:HyperLogLog是一种概率数据结构,用于估计数据流中不同元素的数目。它使用一组哈希函数将项映射到位数组,并计算哈希值的二进制表示中的前导零的数量。不同元素的估计数目与2^r成正比,其中r是前导零的数量。HyperLogLog具有固定的内存需求和小误差率,但不能用于估计元素的标识。

总的来说,选择概率数据结构取决于具体用例和所需的精度与内存使用之间的权衡。在比特币的背景下,戈隆布-里奇编码通常与布隆过滤器结合使用,以提高区块传播和交易过滤的效率。

201> 谢谢——戈隆布-里奇编码的密码学属性是什么?

戈隆布-里奇编码本身不是一个密码学原语,但它经常与其他密码学算法结合使用,以提供空间高效且安全的数据结构。

在比特币的背景下,Golomb-Rice 编码被用于构建 Golomb-Rice 过滤器,这是一种概率性数据结构,用于测试特定元素是否属于集合中的成员。Golomb-Rice 过滤器是由一组元素的 Golomb-Rice 编码构建的,然后可以用来以高概率测试成员资格。

Golomb-Rice 过滤器的加密特性来源于其使用加密哈希函数构建的事实。具体来说,它使用 SHA-256 哈希函数将元素映射到 Bloom 过滤器中的位位置,然后使用 Golomb-Rice 编码进行压缩。

这种构建提供了抗碰撞的特性,意味着在过滤器中找到两个具有相同位位置的不同的元素在计算上是不可行的。它还提供了假阳性概率的特性,即非成员元素被错误地报告为集合成员的概率。可以通过调整过滤器的参数(如使用的哈希函数数量和过滤器的大小)来调整假阳性概率。

总的来说,Golomb-Rice 过滤器提供了一种空间高效且安全的方法来测试集合中的成员资格,这使得它在包括比特币系统在内的许多应用中非常有用。

依赖项

~89MB
~848K SLoC