

 **Questa pagina è riservata ai clienti esistenti del servizio Amazon Glacier che utilizzano Vaults e l'API REST originale del 2012.**

Se stai cercando soluzioni di archiviazione, ti consigliamo di utilizzare le classi di storage Amazon Glacier in Amazon S3, S3 Glacier Instant Retrieval, S3 Glacier Flexible Retrieval e S3 Glacier Deep Archive. Per ulteriori informazioni su queste opzioni di storage, consulta le classi di storage di [Amazon Glacier](https://aws.amazon.com/s3/storage-classes/glacier/).

Amazon Glacier (servizio autonomo originale basato su vault) non accetta più nuovi clienti. Amazon Glacier è un servizio APIs autonomo che archivia i dati in vault ed è distinto dalle classi di storage Amazon S3 e Amazon S3 Glacier. I dati esistenti rimarranno sicuri e accessibili in Amazon Glacier a tempo indeterminato. Non è richiesta alcuna migrazione. Per uno storage di archiviazione a lungo termine a basso costo, AWS consiglia le classi di storage [Amazon S3 Glacier](https://aws.amazon.com/s3/storage-classes/glacier/), che offrono un'esperienza cliente superiore con disponibilità Regione AWS completa, costi inferiori e integrazione dei servizi APIs basata su bucket S3. AWS Se desideri funzionalità avanzate, prendi in considerazione la migrazione alle classi di storage Amazon S3 Glacier utilizzando la [AWS nostra Solutions Guidance per il trasferimento di dati dai vault Amazon Glacier alle classi di storage Amazon S3 Glacier](https://aws.amazon.com/solutions/guidance/data-transfer-from-amazon-s3-glacier-vaults-to-amazon-s3/).

Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.

# Calcolo di checksum
<a name="checksum-calculations"></a>

Durante il caricamento di un archivio, devi includere le intestazioni `x-amz-sha256-tree-hash` e `x-amz-content-sha256`. L'intestazione `x-amz-sha256-tree-hash` è un checksum del payload nel corpo della richiesta. Questo argomento descrive come calcolare l'intestazione `x-amz-sha256-tree-hash`. L'intestazione `x-amz-content-sha256` è un hash dell'intero payload ed è necessaria per l'autorizzazione. Per ulteriori informazioni, consulta [Esempio di calcolo di firma per l'API di streaming](amazon-glacier-signing-requests.md#example-signature-calculation-streaming). 

Il payload della richiesta può essere:

 
+ **Archivio completo:** durante il caricamento di un archivio in un'unica richiesta mediante l'API Upload Archive, l'intero archivio viene inviato nel corpo della richiesta. In questo caso, devi includere il checksum dell'intero archivio. 
+ **Parte di un archivio:** durante il caricamento di un archivio in parti mediante l'API corrispondente, solo una parte dell'archivio viene inviata nel corpo della richiesta. In questo caso, devi includere il checksum di quella parte dell'archivio. Dopo aver caricato tutte le parti, è necessario inviare una richiesta Complete Multipart Upload che deve includere il checksum dell'intero archivio.

Il checksum del payload è una struttura hash SHA-256. È denominata struttura hash in quanto nel processo di calcolo del checksum viene calcolata una struttura di valori hash SHA-256. Il valore hash nella radice è il checksum dell'intero archivio. 

 

**Nota**  
Questa sezione descrive un metodo di calcolo della struttura hash SHA-256. Tuttavia, puoi utilizzare qualsiasi altra procedura purché produca lo stesso risultato.

Per calcolare la struttura hash SHA-256, procedi come segue:

 

1. Per ogni blocco di 1 MB di dati di payload, calcola l'hash SHA-256. L'ultimo blocco di dati può essere inferiore a 1 MB. Ad esempio, se stai caricando un archivio di 3,2 MB, calcoli i valori hash SHA-256 per ognuno dei primi tre blocchi di 1 MB di dati, quindi calcoli l'hash SHA-256 dei restanti 0,2 MB di dati. Questi valori hash formano i nodi foglia della struttura.

1. Crea il livello successivo della struttura.

   1. Concatena i valori hash di due nodi figlio consecutivi e calcola l'hash SHA-256 dei valori hash concatenati. Questa concatenazione e generazione dell'hash SHA-256 produce un nodo padre per i due nodi figlio.

   1. Quando rimane un solo nodo figlio, alza il valore hash al livello successivo nella struttura.

1. Ripeti la fase 2 fino a che la struttura risultante ha una radice. La radice della struttura fornisce un hash dell'intero archivio e una radice della sottostruttura appropriata fornisce l'hash della parte in un caricamento in più parti. 

**Topics**
+ [Esempio di struttura hash 1: caricamento di un archivio in un'unica richiesta](#checksum-calculations-upload-archive-in-single-payload)
+ [Esempio di struttura hash 2: caricamento di un archivio mediante un caricamento in più parti](#checksum-calculations-upload-archive-using-mpu)
+ [Calcolo della struttura hash di un file](#checksum-calculations-examples)
+ [Ottenimento di checksum durante il download di dati](checksum-calculations-range.md)

## Esempio di struttura hash 1: caricamento di un archivio in un'unica richiesta
<a name="checksum-calculations-upload-archive-in-single-payload"></a>

Quando carichi un archivio in un'unica richiesta mediante l'API Upload Archive (consulta [Upload Archive (POST archive)](api-archive-post.md)), il payload della richiesta include l'intero archivio. Di conseguenza, devi includere la struttura hash dell'intero archivio nell'intestazione di richiesta `x-amz-sha256-tree-hash`. Supponi di voler caricare un archivio di 6,5 MB. Il diagramma seguente illustra il processo di creazione dell'hash SHA-256 dell'archivio. Leggi l'archivio e calcola l'hash SHA-256 per ogni blocco di 1 MB. Calcola anche l'hash per i restanti 0,5 MB di dati e quindi crea la struttura come descritto nella procedura precedente.

 

![\[Diagramma che mostra un esempio di tree hash durante il caricamento di un archivio in una singola richiesta.\]](http://docs.aws.amazon.com/it_it/amazonglacier/latest/dev/images/TreeHash-ArchiveUploadSingleRequest.png)


## Esempio di struttura hash 2: caricamento di un archivio mediante un caricamento in più parti
<a name="checksum-calculations-upload-archive-using-mpu"></a>

Il processo di calcolo della struttura hash durante il caricamento di un archivio mediante il caricamento in più parti è identico a quello per il caricamento dell'archivio in un'unica richiesta. L'unica differenza è che in un caricamento in più parti carichi solo una parte dell'archivio in ogni richiesta (utilizzando l'API [Upload Part (PUT uploadID)](api-upload-part.md)), di conseguenza fornisci soltanto il checksum della parte nell'intestazione di richiesta `x-amz-sha256-tree-hash`. Tuttavia, dopo il caricamento di tutte le parti, devi inviare la richiesta Complete Multipart Upload (vedi [Complete Multipart Upload (POST uploadID)](api-multipart-complete-upload.md)) con una struttura hash dell'intero archivio nell'intestazione di richiesta `x-amz-sha256-tree-hash`. 

 

![\[Diagramma che mostra un esempio di tree hash durante il caricamento di un archivio utilizzando un caricamento in più parti.\]](http://docs.aws.amazon.com/it_it/amazonglacier/latest/dev/images/TreeHash-MPU.png)


## Calcolo della struttura hash di un file
<a name="checksum-calculations-examples"></a>

Gli algoritmi illustrati di seguito sono selezionati a scopo dimostrativo. Puoi ottimizzare il codice in funzione delle esigenze del tuo scenario di implementazione. Se utilizzi un Amazon SDK per la programmazione con Amazon Glacier (Amazon Glacier), il calcolo dell'hash dell'albero viene eseguito automaticamente e devi solo fornire il riferimento al file.

**Example 1. Esempio con Java**  
L'esempio seguente mostra come calcolare l'hash dell' SHA256 albero di un file utilizzando Java. Puoi eseguire questo esempio specificando una percorso di file come argomento oppure utilizzare il metodo `TreeHashExample.computeSHA256TreeHash` direttamente nel codice.  

```
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. Esempio con C\$1 .NET**  
L'esempio seguente mostra come calcolare l'hash dell' SHA256 albero di un file. Puoi eseguire questo esempio specificando un percorso di file come argomento.  

```
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;
        }
    }
}
```

# Ottenimento di checksum durante il download di dati
<a name="checksum-calculations-range"></a>

Quando recuperi un archivio utilizzando l'API Initiate Job (vedi [Initiate Job (POST jobs)](api-initiate-job-post.md)), puoi eventualmente specificare un intervallo di archivio da recuperare. Analogamente, quando scarichi i dati utilizzando l'API Get Job Output (vedi [Get Job Output (GET output)](api-job-output-get.md)), puoi eventualmente specificare un intervallo di dati da scaricare. È necessario comprendere due caratteristiche importanti di questi intervalli quando si recuperano e scaricano i dati di un archivio. L'intervallo da recuperare deve essere *allineato in termini di megabyte* all'archivio. L'intervallo da recuperare e quello da scaricare devono essere *allineati alla struttura hash* per poter ricevere valori di checksum durante il download dei dati. La definizione di questi due tipi di allineamenti di intervalli è riportata di seguito:

 
+ Megabyte allineato - Un intervallo [*StartByte*, *EndBytes*] è megabyte (1024\$11024) allineato quando *StartBytes*è divisibile per 1 MB e *EndBytes*più 1 è divisibile per 1 MB o è uguale alla fine dell'archivio specificato (dimensione del byte dell'archivio meno 1). Se si specifica l'API Initiate Job, l'intervallo deve essere obbligatoriamente allineato in termini di megabyte.
+ Tree-hash aligned - Un range [*StartBytes*, *EndBytes*] è l'hash dell'albero allineato rispetto a un archivio se e solo se la radice dell'hash dell'albero costruito sull'intervallo è equivalente a un nodo nell'hash dell'albero dell'intero archivio. L'intervallo da recuperare e quello da scaricare devono essere allineati alla struttura hash per poter ricevere i valori di checksum dei dati scaricati. Per un esempio di intervalli e della relativa relazione con la struttura hash di un archivio, consulta [Esempio di struttura hash: recupero di un intervallo di archivio allineato alla struttura hash](#checksum-calculations-upload-archive-with-ranges). 

  Nota che un intervallo allineato alla struttura hash è anche allineato in termini di megabyte. Tuttavia, un intervallo allineato in termini di megabyte non è necessariamente allineato alla struttura hash. 

Di seguito sono riportati i casi in cui si ottiene un valore di checksum durante il download dei dati in archivio:

 
+ Se non specifichi un intervallo da recuperare nella richiesta Initiate Job e scarichi l'intero archivio nella richiesta Get Job. 
+ Se non specifichi un intervallo da recuperare nella richiesta Initiate Job e specifichi un intervallo allineato alla struttura hash da scaricare nella richiesta Get Job.
+ Se specifichi un intervallo allineato alla struttura hash da recuperare nella richiesta Initiate Job e scarichi l'intero intervallo nella richiesta Get Job. 
+ Se specifichi un intervallo allineato alla struttura hash da recuperare nella richiesta Initiate Job e specifichi un intervallo allineato alla struttura hash da scaricare nella richiesta Get Job. 

Se specifichi un intervallo da recuperare nella richiesta Initiate Job che non è allineato alla struttura hash, puoi comunque ottenere i dati in archivio ma nessun valore di checksum viene restituito quando scarichi i dati nella richiesta Get Job.

## Esempio di struttura hash: recupero di un intervallo di archivio allineato alla struttura hash
<a name="checksum-calculations-upload-archive-with-ranges"></a>

Supponi di avere un archivio di 6,5 MB nel tuo vault e che intendi recuperare 2 MB dell'archivio. Il modo in cui specifichi l'intervallo di 2 MB nella richiesta Initiate Job determina se ricevi i valori di checksum dei dati quando scarichi i dati. Il diagramma seguente illustra due intervalli di 2 MB per l'archivio di 6,5 MB che puoi scaricare. Entrambi gli intervalli sono allineati in termini di megabyte, ma solo uno è allineato alla struttura hash. 

 

![\[Diagramma che mostra il recupero di un intervallo di archivio allineato con tree-hash.\]](http://docs.aws.amazon.com/it_it/amazonglacier/latest/dev/images/TreeHash-ArchiveWithRanges.png)


## Specifica di un intervallo allineato alla struttura hash
<a name="tree-hash-algorithm"></a>

Questa sezione fornisce l'esatta specifica di un intervallo allineato a una struttura hash. Gli intervalli allineati alla struttura hash sono importanti quando scarichi una parte di un archivio e specifichi l'intervallo di dati da recuperare e l'intervallo di dati recuperati da scaricare. Se entrambi questi intervalli sono allineati alla struttura hash, riceverai i valori di checksum quando scarichi i dati. 

Un intervallo [*A*, *B*] è *allineato alla struttura hash* rispetto a un archivio se e solo se, quando una nuova struttura hash viene creata su [*A*, *B*], la radice della struttura hash di quell'intervallo è equivalente a un nodo nella struttura hash dell'intero archivio. Ciò è illustrato nel diagramma in [Esempio di struttura hash: recupero di un intervallo di archivio allineato alla struttura hash](#checksum-calculations-upload-archive-with-ranges). In questa sezione forniamo la specifica per l'allineamento alla struttura hash.

Considera [*P*, *Q*) come la query di intervallo di un archivio di *N* megabyte (MB) e che *P* e *Q* sono multipli di 1 MB. Nota che l'intervallo inclusivo effettivo è [*P* MB, *Q* MB – 1 byte], ma per semplicità, lo presentiamo come [*P*, *Q*). Sulla base di queste considerazioni:

 
+ Se *P* è un numero dispari, un solo intervallo allineato alla struttura hash è possibile, ovvero [*P*, *P* \$11 MB).
+ Se *P* è un numero pari e *k* è il numero massimo, dove *P* può essere scritto come 2*k* \$1 *X*, ci sono al massimo *k* intervalli allineati alla struttura hash che iniziano con *P*. *X* è un numero intero maggiore di 0. Gli intervalli allineati alla struttura hash rientrano nelle seguenti categorie: 
  + In ogni *i*, dove (0 <= *i* <= *k*) e dove *P* \$1 2*i* < *N*, [*P*, *Q* \$1 2*i*) è un intervallo allineato alla struttura hash.
  + *P* = 0 è il caso speciale dove *A* = 2[lgN]\$10