Tree Hash:如何验证范围是否以树形哈希对齐?

时间:2016-06-04 11:10:16

标签: algorithm data-structures binary-tree amazon-glacier

" Tree Hash"是一个类似于Merkle Tree / Tiger Hash Tree的概念,Amazon Glacier使用它来验证给定数据流子集的数据完整性。

为了在检索数据时从Amazon Glacier接收树哈希,指定的字节范围必须是"树形哈希对齐"。

The concept of "tree hash aligned" is described here.

引用开发者文档:

  

范围[A,B]是关于存档的树形哈希对齐当且仅当在[A,B]上构建新的树形哈希时,该范围的树形哈希的根等效于整个存档的树形哈希中的节点。 [...]

     

将[P,Q]视为N兆字节(MB)存档的范围查询,P和Q是1 MB的倍数。请注意,实际包含范围是[P MB,Q MB - 1字节],但为简单起见,我们将其显示为[P,Q]。有了这些考虑,那么

     
      
  • 如果P是奇数,则只有一个可能的树哈希对齐范围 - 即[P,P + 1 MB]。
  •   
  • 如果P是偶数且k是最大数,其中P可以写为2k * X,那么最多有k个树形哈希对齐的范围以P开头.X是大于0的整数。树形哈希对齐范围属于以下类别:      
        
    • 对于每个i,其中(0 <= i <= k)并且其中P + 2i <1。 N,则[P,Q + 2i]是树形哈希对齐范围。
    •   
    • P = 0是A = 2 [lgN] * 0
    • 的特殊情况   
  •   

现在的问题是:如果给定范围[startByte,endByte]是树形哈希对齐的,我如何以编程方式验证?编程语言并不重要。

测试用例:

[0,0) => true
[0,1) => true
[0,2) => false
[0,3) => true
[1,2) => false
[4,5) => true

1 个答案:

答案 0 :(得分:1)

这是 Python is_treehash_aligned 函数的基本实现:

import math

def max_k(x):
    return 1 + max_k(x/2) if x % 2 == 0 else 0

def is_treehash_aligned(P, Q):

    if (Q < P):
        return False
    elif (P % 2 == 1):
        return Q == P
    else:
        ilen = Q - P + 1    # size(interval)
        if  not (((ilen & (ilen - 1)) == 0) and ilen != 0):
            return False    # size(interval) ~ not power of two
        if P == 0:
            return True
        else:
            k = max_k(P)
            i = int(math.log(ilen, 2))
            return i <= k

if (__name__ == "__main__"):
    ranges = [(0, 0), (0, 1), (0, 2), (0, 3), (1, 2), \
              (4, 5), (6, 7), (2, 4), (6, 8), (5, 6), \
              (4, 4), (1, 1), (4194304, 5242879), \
              (4194304, 5242880), (4194304, 5242881)]

    for r in ranges:
        ret = is_treehash_aligned(*r)
        print("[" + str(r[0]) + ", " + str(r[1]) + ") => " + str(ret))

输出结果为:

[0, 0) => True
[0, 1) => True
[0, 2) => False
[0, 3) => True
[1, 2) => False
[4, 5) => True
[6, 7) => True
[2, 4) => False
[6, 8) => False
[5, 6) => False
[4, 4) => True
[1, 1) => True
[4194304, 5242879) => True
[4194304, 5242880) => False
[4194304, 5242881) => False

请注意:

  • 我采用您的符号作为间隔,而不是指令提供的间隔。因此,可以假设每个间隔兆字节对齐
  • 测试用例[4194304, 5242880)的结果与您在原始问题中的结果不同,但我仔细检查了一下,我有点确信它是正确的。
  • 如果已知N,那么在您的测试用例中就不是这种情况,那么当P == 0时,也应该接受任何范围s.t. Q >= floor(N),而不仅仅是那些为2的力量的人。可以对子树进行类似的论证,上没有其他内容。这两种情况都与给定here Tree-Hash Alignment 定义匹配,而不是指令用于识别它。< / LI>

备注:问题和问题description似乎虽然令人困惑。

  1. 测试用例的符号为[A, B),其中A是起始块的索引,B是结束块的索引(包括),假设整个存档由数组组成 - 索引从0开始 N 块大小 1 MB 每个(除了可能是最后一个)。 E.g:

    [0,0) => true
    [0,1) => true
    [0,2) => false
    [0,3) => true
    [1,2) => false
    [4,5) => true
    

    但是,说明假设范围以符号[P MB, Q MB – 1 byte]给出。

  2. 说明 误导

    例如,在这里说:

      

    如果P是偶数且k是最大数,其中P可以写为2k * X,那么最多有k个树形哈希对齐范围以P开头

    power 符号似乎被省略,可能是由于错误的 HTML 代码,因为句子应该“最大的k st { {1}}“

    另一个例子是:

      

    对于每个i,其中(0 <= i <= k)并且其中P + 2i <1。 N,则[P,Q + 2i]是树形哈希对齐范围。

    例如假设P = (2^k)*XQ = P + 1i > 0。然后,时间间隔k > 0的大小为[P, Q + 2^i)。但是,通过构造,不存在具有大于1的奇数大小的 tree-hash 对齐范围。命题应该是:“[...],然后= Q + 2^i - P = P + 1 + 2^i - P = 2^i + 1 > 1是一个树形哈希对齐范围”