public static String calculateTreeHash ( List < byte [ ] > checksums ) throws AmazonClientException { /* * The tree hash algorithm involves concatenating adjacent pairs of * individual checksums, then taking the checksum of the resulting bytes * and storing it, then recursing on this new list until there is only * one element. Any final odd-numbered parts at each step are carried * over to the next iteration as-is. */ List < byte [ ] > hashes = new ArrayList < byte [ ] > ( ) ; hashes . addAll ( checksums ) ; while ( hashes . size ( ) > 1 ) { List < byte [ ] > treeHashes = new ArrayList < byte [ ] > ( ) ; for ( int i = 0 ; i < hashes . size ( ) / 2 ; i ++ ) { byte [ ] firstPart = hashes . get ( 2 * i ) ; byte [ ] secondPart = hashes . get ( 2 * i + 1 ) ; byte [ ] concatenation = new byte [ firstPart . length + secondPart . length ] ; System . arraycopy ( firstPart , 0 , concatenation , 0 , firstPart . length ) ; System . arraycopy ( secondPart , 0 , concatenation , firstPart . length , secondPart . length ) ; try { treeHashes . add ( computeSHA256Hash ( concatenation ) ) ; } catch ( Exception e ) { throw new AmazonClientException ( "Unable to compute hash" , e ) ; } } if ( hashes . size ( ) % 2 == 1 ) { treeHashes . add ( hashes . get ( hashes . size ( ) - 1 ) ) ; } hashes = treeHashes ; } return BinaryUtils . toHex ( hashes . get ( 0 ) ) ; }
Returns the hex encoded binary tree hash for the individual checksums given . The sums are assumed to have been generated from sequential 1MB portions of a larger file with the possible exception of the last part which may be less than a full MB .