代码之家  ›  专栏  ›  技术社区  ›  osgx

bup(基于git的映像备份)如何计算存储对象的哈希值

  •  2
  • osgx  · 技术社区  · 9 年前

    bup 备份程序( https://github.com/bup/bup )基于一些想法和功能 git 用于压缩存储虚拟机映像的版本控制系统。

    在里面 打嗝 bup ls 子命令,当 -s 选项被传递(in man bup-ls 只是“ -s、 --hash:显示每个文件/目录的哈希。 “)。但类似sha1的散列不等于 sha1sum 原始文件的输出。

    起初的 吉特 通过在数据前面加上“blob NNN\0”字符串来计算数据的sha1哈希,其中NNN是对象的字节大小,写为十进制,根据 How does git compute file hashes? https://stackoverflow.com/a/28881708/

    我测试了前缀“blob NNN\0”,但仍然不是相同的sha1总和。

    bup中使用的计算文件哈希和的方法是什么?它是线性sha1还是类似Merkle树的树型变体?目录的哈希是什么?

    的来源 ls bup命令是 https://github.com/bup/bup/blob/master/lib/bup/ls.py ,散列只是以十六进制打印,但散列是在哪里生成的?

    def node_info(n, name, 
        ''' ....
        if show_hash:
            result += "%s " % n.hash.encode('hex')
    

    是在创建bup备份时生成的哈希吗 bup index + bup save 命令),然后打印出来 bup ls(错误) ; 还是每 bup ls(错误) 可以作为bup备份的完整性测试吗?

    1 回复  |  直到 9 年前
        1
  •  0
  •   Leon    9 年前

    bup 将所有数据存储在裸git存储库中(默认情况下位于 ~/.bup ). 因此 打嗝 的哈希计算方法与 git .

    然而,与git的一个重要区别是 打嗝 可能会将文件拆分为块。如果 打嗝 决定将文件拆分为块,然后在存储库中将文件表示为树而不是blob。那样的话 打嗝 吉特 对应树的哈希。

    以下脚本演示了:

    bup_hash_test测试

    #!/bin/bash
    
    bup init
    BUPTEST=/tmp/bup_test
    function test_bup_hash()
    {
        bup index $BUPTEST &> /dev/null
        bup save -n buptest $BUPTEST &> /dev/null
        local buphash=$(bup ls -s buptest/latest$BUPTEST|cut -d' ' -f 1)
        echo "bup's hash: $buphash"
        echo "git's hash: $(git hash-object $BUPTEST)"
        echo git --git-dir \~/.bup cat-file -p $buphash
        git --git-dir ~/.bup cat-file -p $buphash
    }
    
    cat > $BUPTEST <<'END'
        http://pkgsrc.se/sysutils/bup
        http://cvsweb.netbsd.org/bsdweb.cgi/pkgsrc/sysutils/bup/
    END
    
    test_bup_hash
    
    echo
    echo
    
    echo " -1" >> $BUPTEST
    
    echo "After appending ' -1' line:"
    test_bup_hash
    
    echo
    echo
    
    echo "After replacing '-' with '#':"
    sed -i 's/-/#/' $BUPTEST
    test_bup_hash
    

    输出:

    $ ./bup_hash_test
    Initialized empty Git repository in ~/.bup/
    bup's hash: b52baef90c17a508115ce05680bbb91d1d7bfd8d
    git's hash: b52baef90c17a508115ce05680bbb91d1d7bfd8d
    git --git-dir ~/.bup cat-file -p b52baef90c17a508115ce05680bbb91d1d7bfd8d
        http://pkgsrc.se/sysutils/bup
        http://cvsweb.netbsd.org/bsdweb.cgi/pkgsrc/sysutils/bup/
    
    
    After appending ' -1' line:
    bup's hash: c95b4a1fe1956418cb0e58e0a2c519622d8ce767
    git's hash: b5bc4094328634ce6e2f4c41458514bab5f5cd7e
    git --git-dir ~/.bup cat-file -p c95b4a1fe1956418cb0e58e0a2c519622d8ce767
    100644 blob aa7770f6a52237f29a5d10b350fe877bf4626bd6    00
    100644 blob d00491fd7e5bb6fa28c517a0bb32b8b506539d4d    61
    
    
    After replacing '-' with '#':
    bup's hash: cda9a69f1cbe66ff44ea6530330e51528563e32a
    git's hash: cda9a69f1cbe66ff44ea6530330e51528563e32a
    git --git-dir ~/.bup cat-file -p cda9a69f1cbe66ff44ea6530330e51528563e32a
        http://pkgsrc.se/sysutils/bup
        http://cvsweb.netbsd.org/bsdweb.cgi/pkgsrc/sysutils/bup/
     #1
    

    正如我们所见,何时 打嗝 的和 吉特 的哈希匹配,则为 打嗝 存储库是具有预期内容的blob。什么时候 打嗝 的和 吉特 的哈希不匹配,对象与 打嗝 的哈希是一棵树。该树中Blob的内容对应于完整文件的片段:

    $ git --git-dir ~/.bup cat-file -p aa7770f6a52237f29a5d10b350fe877bf4626bd6
        http://pkgsrc.se/sysutils/bup
        http://cvsweb.netbsd.org/bsdweb.cgi/pkgsrc/sysutils/bup/
     -$ git --git-dir ~/.bup cat-file -p d00491fd7e5bb6fa28c517a0bb32b8b506539d4d
    1