

 **Halaman ini hanya untuk pelanggan lama layanan Amazon Glacier menggunakan Vaults dan REST API asli dari 2012.**

Jika Anda mencari solusi penyimpanan arsip, sebaiknya gunakan kelas penyimpanan Amazon Glacier di Amazon S3, S3 Glacier Instant Retrieval, S3 Glacier Flexible Retrieval, dan S3 Glacier Deep Archive. Untuk mempelajari lebih lanjut tentang opsi penyimpanan ini, lihat kelas penyimpanan [Amazon Glacier](https://aws.amazon.com/s3/storage-classes/glacier/).

Amazon Glacier (layanan berbasis brankas mandiri asli) tidak lagi menerima pelanggan baru. Amazon Glacier adalah layanan mandiri dengan miliknya APIs sendiri yang menyimpan data di brankas dan berbeda dari Amazon S3 dan kelas penyimpanan Amazon S3 Glacier. Data Anda yang ada akan tetap aman dan dapat diakses di Amazon Glacier tanpa batas waktu. Tidak diperlukan migrasi. Untuk penyimpanan arsip jangka panjang berbiaya rendah, AWS rekomendasikan kelas [penyimpanan Amazon S3 Glacier](https://aws.amazon.com/s3/storage-classes/glacier/), yang memberikan pengalaman pelanggan yang unggul dengan APIs berbasis ember S3, ketersediaan penuh, biaya lebih rendah, Wilayah AWS dan integrasi layanan. AWS Jika Anda ingin meningkatkan kemampuan, pertimbangkan untuk bermigrasi ke kelas penyimpanan Amazon S3 Glacier dengan menggunakan [Panduan Solusi AWS kami untuk mentransfer data dari kubah Amazon Glacier ke kelas penyimpanan Amazon S3 Glacier](https://aws.amazon.com/solutions/guidance/data-transfer-from-amazon-s3-glacier-vaults-to-amazon-s3/).

Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.

# Checksum Komputasi
<a name="checksum-calculations"></a>

Saat mengunggah arsip, Anda harus menyertakan header `x-amz-sha256-tree-hash` dan `x-amz-content-sha256`. Header `x-amz-sha256-tree-hash` adalah checksum muatan di isi permintaan Anda. Topik ini menjelaskan cara menghitung header `x-amz-sha256-tree-hash`. Header `x-amz-content-sha256` adalah hash seluruh muatan dan diperlukan untuk otorisasi. Untuk informasi selengkapnya, lihat [Contoh Perhitungan Tanda Tangan untuk API Streaming](amazon-glacier-signing-requests.md#example-signature-calculation-streaming). 

Muatan permintaan Anda dapat berupa:

 
+ **Seluruh arsip—** Saat mengunggah arsip dalam satu permintaan menggunakan API Unggap Arsip, Anda mengirim seluruh arsip di isi permintaan. Dalam hal ini, Anda harus menyertakan checksum seluruh arsip. 
+ **Bagian arsip—** Saat mengunggah arsip di bagian menggunakan API unggahan multipart, Anda hanya mengirim sebagian arsip di isi permintaan. Dalam hal ini, Anda menyertakan checksum bagian arsip. Dan setelah Anda mengunggah semua bagian, Anda mengirim permintaan Complete Multipart Upload (Selesaikan Unggahan Multipart), yang harus mencakup checksum seluruh arsip.

Checksum muatan adalah hash tree SHA-256. Ini disebut hash tree karena dalam proses komputasi checksum, Anda menghitung pohon nilai hash SHA-256. Nilai hash pada akar adalah checksum untuk seluruh arsip. 

 

**catatan**  
Bagian ini menjelaskan cara menghitung hash pohon SHA-256. Namun, Anda dapat menggunakan prosedur apa pun selama hasilnya yang sama.

Anda menghitung hash tree SHA-256 sebagai berikut:

 

1. Untuk setiap potongan data muatan 1 MB, hitung hash SHA-256. Potongan data terakhir dapat kurang dari 1 MB. Misalnya, jika Anda mengunggah arsip berukuran 3,2 MB, Anda menghitung nilai hash SHA-256 untuk masing-masing tiga potongan data 1 MB pertama, lalu menghitung hash SHA-256 dari 0,2 MB data yang tersisa. Nilai hash ini membentuk node daun pokok.

1. Bangun tingkat berikutnya dari pohon.

   1. Gabungkan dua nilai hash node turunan berturut-turut dan hitung hash SHA-256 dari gabungan nilai hash. Rangkaian dan pembuatan hash SHA-256 ini menghasilkan node induk untuk dua node turunan.

   1. Jika hanya satu node anak yang tersisa, promosikan nilai hash itu ke tingkat berikutnya di pohon.

1. Ulangi langkah 2 sampai pohon yang dihasilkan memiliki akar. Akar pohon menyediakan hash seluruh arsip dan akar subpohom yang sesuai menyediakan hash untuk bagian dalam upload multipart. 

**Topics**
+ [Contoh Hash Pohon 1: Mengunggah arsip dalam satu permintaan](#checksum-calculations-upload-archive-in-single-payload)
+ [Contih Hash Pohon 2: Mengunggah arsip menggunakan unggahan multipart](#checksum-calculations-upload-archive-using-mpu)
+ [Menghitung Hash Pohon File](#checksum-calculations-examples)
+ [Menerima Checksum Saat Mengunduh Data](checksum-calculations-range.md)

## Contoh Hash Pohon 1: Mengunggah arsip dalam satu permintaan
<a name="checksum-calculations-upload-archive-in-single-payload"></a>

Saat Anda mengunggah arsip dalam permintaan tunggal menggunakan API Unggah Arsip (lihat [Mengunggah Arsip (POST archive)](api-archive-post.md)), muatan permintaan menyertakan seluruh arsip. Dengan demikian, Anda harus menyertakan hash pohon seluruh arsip di header permintaan `x-amz-sha256-tree-hash`. Misalkan Anda ingin mengunggah arsip sebesar 6,5 MB. Diagram berikut menggambarkan proses pembuatan hash SHA-256 arsip. Anda membaca arsip dan menghitung hash SHA-256 untuk setiap potongan 1 MB. Anda juga menghitung hash untuk 0,5 MB data yang tersisa, lalu membangun pohon seperti yang diuraikan dalam prosedur sebelumnya.

 

![\[Diagram yang menunjukkan contoh hash pohon mengunggah arsip dalam satu permintaan.\]](http://docs.aws.amazon.com/id_id/amazonglacier/latest/dev/images/TreeHash-ArchiveUploadSingleRequest.png)


## Contih Hash Pohon 2: Mengunggah arsip menggunakan unggahan multipart
<a name="checksum-calculations-upload-archive-using-mpu"></a>

Proses komputasi hash pohon saat mengunggah arsip menggunakan unggahan multipart sama seperti saat mengunggah arsip dalam permintaan tunggal. Satu-satunya perbedaan adalah dalam unggahan multipart, Anda hanya mengunggah sebagian arsip dalam setiap permintaan (menggunakan API [Mengunggah Bagian (PUT UploadID)](api-upload-part.md)), dan karena itu, Anda memberikan checksum hanya bagian dalam header permintaan `x-amz-sha256-tree-hash`. Namun, setelah Anda mengunggah semua bagian, Anda harus mengirim permintaan Complete Multipart Upload (Selesaikan Unggahan Multipart) (lihat [Menyelesaikan Unggahan Multipart (POST uploadID)](api-multipart-complete-upload.md)) dengan pohon hash seluruh arsip di header permintaan `x-amz-sha256-tree-hash`. 

 

![\[Diagram yang menunjukkan contoh hash pohon mengunggah arsip menggunakan unggahan multipart.\]](http://docs.aws.amazon.com/id_id/amazonglacier/latest/dev/images/TreeHash-MPU.png)


## Menghitung Hash Pohon File
<a name="checksum-calculations-examples"></a>

Algoritma yang ditampilkan di sini dipilih untuk tujuan demonstrasi. Anda dapat mengoptimalkan kode yang diperlukan untuk skenario implementasi Anda. Jika Anda menggunakan Amazon SDK untuk memprogram melawan Amazon Glacier (Amazon Glacier), perhitungan hash pohon dilakukan untuk Anda dan Anda hanya perlu memberikan referensi file.

**Example 1: Contoh Java**  
Contoh berikut menunjukkan bagaimana menghitung hash SHA256 pohon dari file menggunakan Java. Anda dapat menjalankan contoh ini dengan menyediakan lokasi file sebagai argumen atau Anda dapat menggunakan metode `TreeHashExample.computeSHA256TreeHash` langsung dari kode Anda.  

```
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class TreeHashExample {

static final int ONE_MB = 1024 * 1024;

    /**
     * Compute the Hex representation of the SHA-256 tree hash for the specified
     * File
     * 
     * @param args
     *            args[0]: a file to compute a SHA-256 tree hash for
     */
    public static void main(String[] args) {

        if (args.length < 1) {
            System.err.println("Missing required filename argument");
            System.exit(-1);
        }

        File inputFile = new File(args[0]);
        try {

            byte[] treeHash = computeSHA256TreeHash(inputFile);
            System.out.printf("SHA-256 Tree Hash = %s\n", toHex(treeHash));

        } catch (IOException ioe) {
            System.err.format("Exception when reading from file %s: %s", inputFile,
                    ioe.getMessage());
            System.exit(-1);

        } catch (NoSuchAlgorithmException nsae) {
            System.err.format("Cannot locate MessageDigest algorithm for SHA-256: %s",
                    nsae.getMessage());
            System.exit(-1);
        }
    }

    /**
     * Computes the SHA-256 tree hash for the given file
     * 
     * @param inputFile
     *            a File to compute the SHA-256 tree hash for
     * @return a byte[] containing the SHA-256 tree hash
     * @throws IOException
     *             Thrown if there's an issue reading the input file
     * @throws NoSuchAlgorithmException
     */
    public static byte[] computeSHA256TreeHash(File inputFile) throws IOException,
            NoSuchAlgorithmException {

        byte[][] chunkSHA256Hashes = getChunkSHA256Hashes(inputFile);
        return computeSHA256TreeHash(chunkSHA256Hashes);
    }

    /**
     * Computes a SHA256 checksum for each 1 MB chunk of the input file. This
     * includes the checksum for the last chunk even if it is smaller than 1 MB.
     * 
     * @param file
     *            A file to compute checksums on
     * @return a byte[][] containing the checksums of each 1 MB chunk
     * @throws IOException
     *             Thrown if there's an IOException when reading the file
     * @throws NoSuchAlgorithmException
     *             Thrown if SHA-256 MessageDigest can't be found
     */
    public static byte[][] getChunkSHA256Hashes(File file) throws IOException,
            NoSuchAlgorithmException {

        MessageDigest md = MessageDigest.getInstance("SHA-256");

        long numChunks = file.length() / ONE_MB;
        if (file.length() % ONE_MB > 0) {
            numChunks++;
        }

        if (numChunks == 0) {
            return new byte[][] { md.digest() };
        }

        byte[][] chunkSHA256Hashes = new byte[(int) numChunks][];
        FileInputStream fileStream = null;

        try {
            fileStream = new FileInputStream(file);
            byte[] buff = new byte[ONE_MB];

            int bytesRead;
            int idx = 0;
            int offset = 0;

            while ((bytesRead = fileStream.read(buff, offset, ONE_MB)) > 0) {
                md.reset();
                md.update(buff, 0, bytesRead);
                chunkSHA256Hashes[idx++] = md.digest();
                offset += bytesRead;
            }

            return chunkSHA256Hashes;

        } finally {
            if (fileStream != null) {
                try {
                    fileStream.close();
                } catch (IOException ioe) {
                    System.err.printf("Exception while closing %s.\n %s", file.getName(),
                            ioe.getMessage());
                }
            }
        }
    }

    /**
     * Computes the SHA-256 tree hash for the passed array of 1 MB chunk
     * checksums.
     * 
     * This method uses a pair of arrays to iteratively compute the tree hash
     * level by level. Each iteration takes two adjacent elements from the
     * previous level source array, computes the SHA-256 hash on their
     * concatenated value and places the result in the next level's destination
     * array. At the end of an iteration, the destination array becomes the
     * source array for the next level.
     * 
     * @param chunkSHA256Hashes
     *            An array of SHA-256 checksums
     * @return A byte[] containing the SHA-256 tree hash for the input chunks
     * @throws NoSuchAlgorithmException
     *             Thrown if SHA-256 MessageDigest can't be found
     */
    public static byte[] computeSHA256TreeHash(byte[][] chunkSHA256Hashes)
            throws NoSuchAlgorithmException {

        MessageDigest md = MessageDigest.getInstance("SHA-256");

        byte[][] prevLvlHashes = chunkSHA256Hashes;

        while (prevLvlHashes.length > 1) {

            int len = prevLvlHashes.length / 2;
            if (prevLvlHashes.length % 2 != 0) {
                len++;
            }

            byte[][] currLvlHashes = new byte[len][];

            int j = 0;
            for (int i = 0; i < prevLvlHashes.length; i = i + 2, j++) {

                // If there are at least two elements remaining
                if (prevLvlHashes.length - i > 1) {

                    // Calculate a digest of the concatenated nodes
                    md.reset();
                    md.update(prevLvlHashes[i]);
                    md.update(prevLvlHashes[i + 1]);
                    currLvlHashes[j] = md.digest();

                } else { // Take care of remaining odd chunk
                    currLvlHashes[j] = prevLvlHashes[i];
                }
            }

            prevLvlHashes = currLvlHashes;
        }

        return prevLvlHashes[0];
    }

    /**
     * Returns the hexadecimal representation of the input byte array
     * 
     * @param data
     *            a byte[] to convert to Hex characters
     * @return A String containing Hex characters
     */
    public static String toHex(byte[] data) {
        StringBuilder sb = new StringBuilder(data.length * 2);

        for (int i = 0; i < data.length; i++) {
            String hex = Integer.toHexString(data[i] & 0xFF);

            if (hex.length() == 1) {
                // Append leading zero.
                sb.append("0");
            }
            sb.append(hex);
        }
        return sb.toString().toLowerCase();
    }
}
```

**Example 2: Contoh .NET C\$1**  
Contoh berikut menunjukkan bagaimana menghitung hash SHA256 pohon dari sebuah file. Anda dapat menjalankan contoh ini dengan menyediakan lokasi file sebagai argumen.  

```
using System;
using System.IO;

using System.Security.Cryptography;

namespace ExampleTreeHash
{
    class Program
    {
        static int ONE_MB = 1024 * 1024;

        /**
        * Compute the Hex representation of the SHA-256 tree hash for the
        * specified file
        * 
        * @param args
        *            args[0]: a file to compute a SHA-256 tree hash for
        */
        public static void Main(string[] args)
        {
            if (args.Length < 1)
            {
                Console.WriteLine("Missing required filename argument");
                Environment.Exit(-1);
            }
            FileStream inputFile = File.Open(args[0], FileMode.Open, FileAccess.Read);
            try
            {
                byte[] treeHash = ComputeSHA256TreeHash(inputFile);
                Console.WriteLine("SHA-256 Tree Hash = {0}", BitConverter.ToString(treeHash).Replace("-", "").ToLower());
                Console.ReadLine();
                Environment.Exit(-1);
            }
            catch (IOException ioe)
            {
                Console.WriteLine("Exception when reading from file {0}: {1}",
                    inputFile, ioe.Message);
                Console.ReadLine();
                Environment.Exit(-1);
            }
            catch (Exception e)
            {
                Console.WriteLine("Cannot locate MessageDigest algorithm for SHA-256: {0}",
                    e.Message);
                Console.WriteLine(e.GetType());
                Console.ReadLine();
                Environment.Exit(-1);
            }
            Console.ReadLine();
        }


        /**
         * Computes the SHA-256 tree hash for the given file
         * 
         * @param inputFile
         *            A file to compute the SHA-256 tree hash for
         * @return a byte[] containing the SHA-256 tree hash
         */
        public static byte[] ComputeSHA256TreeHash(FileStream inputFile)
        {
            byte[][] chunkSHA256Hashes = GetChunkSHA256Hashes(inputFile);
            return ComputeSHA256TreeHash(chunkSHA256Hashes);
        }


        /**
         * Computes a SHA256 checksum for each 1 MB chunk of the input file. This
         * includes the checksum for the last chunk even if it is smaller than 1 MB.
         * 
         * @param file
         *            A file to compute checksums on
         * @return a byte[][] containing the checksums of each 1MB chunk
         */
        public static byte[][] GetChunkSHA256Hashes(FileStream file)
        {
            long numChunks = file.Length / ONE_MB;
            if (file.Length % ONE_MB > 0)
            {
                numChunks++;
            }

            if (numChunks == 0)
            {
                return new byte[][] { CalculateSHA256Hash(null, 0) };
            }
            byte[][] chunkSHA256Hashes = new byte[(int)numChunks][];

            try
            {
                byte[] buff = new byte[ONE_MB];

                int bytesRead;
                int idx = 0;

                while ((bytesRead = file.Read(buff, 0, ONE_MB)) > 0)
                {
                    chunkSHA256Hashes[idx++] = CalculateSHA256Hash(buff, bytesRead);
                }
                return chunkSHA256Hashes;
            }
            finally
            {
                if (file != null)
                {
                    try
                    {
                        file.Close();
                    }
                    catch (IOException ioe)
                    {
                        throw ioe;
                    }
                }
            }

        }

        /**
         * Computes the SHA-256 tree hash for the passed array of 1MB chunk
         * checksums.
         * 
         * This method uses a pair of arrays to iteratively compute the tree hash
         * level by level. Each iteration takes two adjacent elements from the
         * previous level source array, computes the SHA-256 hash on their
         * concatenated value and places the result in the next level's destination
         * array. At the end of an iteration, the destination array becomes the
         * source array for the next level.
         * 
         * @param chunkSHA256Hashes
         *            An array of SHA-256 checksums
         * @return A byte[] containing the SHA-256 tree hash for the input chunks
         */
        public static byte[] ComputeSHA256TreeHash(byte[][] chunkSHA256Hashes)
        {
            byte[][] prevLvlHashes = chunkSHA256Hashes;
            while (prevLvlHashes.GetLength(0) > 1)
            {

                int len = prevLvlHashes.GetLength(0) / 2;
                if (prevLvlHashes.GetLength(0) % 2 != 0)
                {
                    len++;
                }

                byte[][] currLvlHashes = new byte[len][];

                int j = 0;
                for (int i = 0; i < prevLvlHashes.GetLength(0); i = i + 2, j++)
                {

                    // If there are at least two elements remaining
                    if (prevLvlHashes.GetLength(0) - i > 1)
                    {

                        // Calculate a digest of the concatenated nodes
                        byte[] firstPart = prevLvlHashes[i];
                        byte[] secondPart = prevLvlHashes[i + 1];
                        byte[] concatenation = new byte[firstPart.Length + secondPart.Length];
                        System.Buffer.BlockCopy(firstPart, 0, concatenation, 0, firstPart.Length);
                        System.Buffer.BlockCopy(secondPart, 0, concatenation, firstPart.Length, secondPart.Length);

                        currLvlHashes[j] = CalculateSHA256Hash(concatenation, concatenation.Length);

                    }
                    else
                    { // Take care of remaining odd chunk
                        currLvlHashes[j] = prevLvlHashes[i];
                    }
                }

                prevLvlHashes = currLvlHashes;
            }

            return prevLvlHashes[0];
        }

        public static byte[] CalculateSHA256Hash(byte[] inputBytes, int count)
        {
            SHA256 sha256 = System.Security.Cryptography.SHA256.Create();
            byte[] hash = sha256.ComputeHash(inputBytes, 0, count);
            return hash;
        }
    }
}
```

# Menerima Checksum Saat Mengunduh Data
<a name="checksum-calculations-range"></a>

Ketika Anda mengambil arsip menggunakan API Mulai Tugas (lihat [Memulai Tugas (POST jobs)](api-initiate-job-post.md)), Anda dapat secara opsional menentukan rentang untuk mengambil arsip. Demikian pula, ketika Anda mengunduh data Anda menggunakan API Dapatkan Hasil Tugas (lihat [Mendapatkan Output Tugas (GET output)](api-job-output-get.md)), Anda dapat secara opsional menentukan rentang data yang akan diunduh. Ada dua karakteristik dari rentang ini yang penting untuk dipahami saat Anda mengambil dan mengunduh data arsip Anda. Rentang yang diambil harus *megabyte selaras* dengan arsip. Kedua rentang yang diambil dan kisaran yang diunduh harus *hash pohon yang diseleraskan* untuk menerima nilai checksum saat Anda mengunduh data Anda. Definisi dua tipe penyelarasan rentang ini adalah sebagai berikut:

 
+ Megabyte selaras - Rentang [*StartByte*, *EndBytes*] adalah megabyte (1024\$11024) sejajar bila habis *StartBytes*dibagi 1 MB dan *EndBytes*ditambah 1 habis dibagi 1 MB atau sama dengan akhir arsip yang ditentukan (ukuran byte arsip dikurangi 1). Rentang yang digunakan dalam API Mulai Tugas, jika ditentukan, harus megabyte selaras.
+ Tree-hash aligned - Rentang [*StartBytes*, *EndBytes*] adalah hash pohon yang disejajarkan sehubungan dengan arsip jika dan hanya jika akar hash pohon yang dibangun di atas rentang setara dengan simpul di hash pohon dari seluruh arsip. Kedua rentang yang diambil dan kisaran yang diunduh harus hash pohon selaras agar dapat menerima nilai checksum untuk data yang Anda unduh. Untuk contoh rentang dan hubungannya dengan hash pohon arsip, lihat [Contoh Hash Pohon: Mengambil rentang arsip yang merupakan hash pohon selaras](#checksum-calculations-upload-archive-with-ranges). 

  Perhatikan bahwa rentang yang merupakan hash pohon selaras juga megabyte selaras. Namun, rentang megabyte selaras belum tentu hash pohon selaras. 

Kasus berikut menjelaskan ketika Anda menerima nilai checksum saat Anda mengunduh data arsip Anda:

 
+ Jika Anda tidak menentukan rentang yang diambil dalam permintaan Initiate Job (Mulai Tugas) dan Anda mengunduh seluruh arsip dalam Permintaan Get Job (Dapatkan Tugas). 
+ Jika Anda tidak menentukan rentang yang diambil dalam permintaan Initiate Job (Mulai Tugas) dan Anda menentukan rentang hash pohon selaras yang diunduh dalam Permintaan Get Job (Dapatkan Tugas).
+ Jika Anda menentukan rentang hash pohon selaras yang diambil dalam permintaan Initiate Job (Mulai Tugas) dan Anda mengunduh seluruh rentang dalam Permintaan Get Job (Dapatkan Tugas). 
+ Jika Anda menentukan rentang hash pohon selaras yang diambil dalam permintaan Initiate Job (Mulai Tugas) dan Anda menentukan rentang hash tree selaras yang diunduh di Permintaan Get Job (Dapatkan Tugas). 

Jika Anda menentukan rentang yang diambil dalam permintaan Initiate Job (Mulai Tugas) yang bukan hash pohon selaras, Anda masih bisa mendapatkan data arsip Anda, tetapi tidak ada nilai checksum yang dikembalikan ketika Anda mengunggah data dalam Permintaan Get Job (Dapatkan Tugas).

## Contoh Hash Pohon: Mengambil rentang arsip yang merupakan hash pohon selaras
<a name="checksum-calculations-upload-archive-with-ranges"></a>

Misalkan Anda memiliki arsip sebesar 6,5 MB di vault Anda dan Anda ingin mengambil arsip sebesar 2 MB. Cara Anda menentukan rentang 2 MB dalam permintaan Initiate Job (Mulai Tugas) menentukan apakah Anda menerima nilai checksum data saat Anda mengunduh data. Diagram berikut menggambarkan dua rentang 2 MB untuk arsip berukuran 6,5 MB yang dapat Anda unduh. Kedua rentang adalah megabyte selaras, tetapi hanya satu yang merupakan hash pohon selaras. 

 

![\[Diagram yang menunjukkan pengambilan rentang arsip yang sejajar dengan hash pohon.\]](http://docs.aws.amazon.com/id_id/amazonglacier/latest/dev/images/TreeHash-ArchiveWithRanges.png)


## Spesifikasi Rentang Hash Pohon Selaras
<a name="tree-hash-algorithm"></a>

Bagian ini memberikan spesifikasi yang tepat untuk apa yang merupakan rentang hash pohon selaras. Rentang hash pohon selaras penting ketika Anda mengunduh sebagian arsip dan Anda menentukan rentang data yang diambil dan rentang yang diunduh dari data yang diambil. Jika kedua rentang ini adalah hash pohon selaras, Anda akan menerima data checksum ketika Anda mengunduh data. 

Rentang [*A*, *B*] adalah *hash pohon selaras* yang berkenaan dengan arsip jika dan hanya jika hash pohon baru dibangun di atas [*A*, *B*], akar hash pohon dari rentang tersebut sama dengan node di hash pohon seluruh arsip. Anda dapat melihat ini ditunjukkan dalam diagram di [Contoh Hash Pohon: Mengambil rentang arsip yang merupakan hash pohon selaras](#checksum-calculations-upload-archive-with-ranges). Pada bagian ini, kami menyediakan spesifikasi untuk penyelarasan hash pohon.

Pertimbangkan [*P*, *Q*) sebagai kueri rentang untuk arsip *N* megabyte (MB) dan *P* serta *Q* adalah kelipatan satu MB. Perhatikan bahwa rentang inklusif sebenarnya adalah [*P* MB, *Q* MB – 1 byte], tetapi agar ringkas, kami menampilkannya sebagai [*P*, *Q*). Dengan pertimbangan ini, maka

 
+ Jika *P* adalah angka ganjil, hanya ada satu kemungkinan rentang hash pohon selaras—yaitu [*P*, *P* \$1 1 MB).
+ Jika *P* adalah bilangan genap dan *k* adalah jumlah maksimum, dengan *P* yang dapat ditulis sebagai 2*k* \$1 *X*, ada rentang hash pohon selaras *k* paling banyak yang dimulai dengan *P*. *X* adalah bilangan bulat yang lebih besar dari 0. Rentang hash pohon selaras masuk dalam kategori berikut: 
  + Untuk setiap *i*, dengan (0 <= *i* <= *k*) dan dengan *P* \$1 2*i* < *N*, maka [*P*, *Q* \$1 2*i*) adalah rentang hash pohon selaras.
  + *P* = 0 adalah kasus khusus dengan *A* = 2[lgN]\$10