diff options
author | Andrew Dolgov <[email protected]> | 2022-11-23 21:14:33 +0300 |
---|---|---|
committer | Andrew Dolgov <[email protected]> | 2022-11-23 21:14:33 +0300 |
commit | 0c8af4992cb0f7589dcafaad65ada12753c64594 (patch) | |
tree | 18e83d068c3e7dd2499331de977782b382279396 /vendor/aws/aws-sdk-php/src/Glacier/TreeHash.php |
initial
Diffstat (limited to 'vendor/aws/aws-sdk-php/src/Glacier/TreeHash.php')
-rw-r--r-- | vendor/aws/aws-sdk-php/src/Glacier/TreeHash.php | 118 |
1 files changed, 118 insertions, 0 deletions
diff --git a/vendor/aws/aws-sdk-php/src/Glacier/TreeHash.php b/vendor/aws/aws-sdk-php/src/Glacier/TreeHash.php new file mode 100644 index 0000000..9289725 --- /dev/null +++ b/vendor/aws/aws-sdk-php/src/Glacier/TreeHash.php @@ -0,0 +1,118 @@ +<?php +namespace Aws\Glacier; + +use Aws\HashInterface; + +/** + * Encapsulates the creation of a tree hash from streamed data + */ +class TreeHash implements HashInterface +{ + const MB = 1048576; + const EMPTY_HASH = 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'; + + /** @var string Algorithm used for hashing. */ + private $algorithm; + + /** @var string Buffered data that has not yet been hashed. */ + private $buffer; + + /** @var array Binary checksums from which the tree hash is derived. */ + private $checksums = []; + + /** @var string Resulting hash in binary form. */ + private $hash; + + public function __construct($algorithm = 'sha256') + { + $this->algorithm = $algorithm; + $this->reset(); + } + + /** + * {@inheritdoc} + * @throws \LogicException if the root tree hash is already calculated + */ + public function update($data) + { + // Error if hash is already calculated. + if ($this->hash) { + throw new \LogicException('You may not add more data to a ' + . 'complete tree hash.'); + } + + // Buffer incoming data. + $this->buffer .= $data; + + // When there is more than a MB of data, create a checksum. + while (strlen($this->buffer) >= self::MB) { + $data = substr($this->buffer, 0, self::MB); + $this->buffer = substr($this->buffer, self::MB) ?: ''; + $this->checksums[] = hash($this->algorithm, $data, true); + } + + return $this; + } + + /** + * Add a checksum to the tree hash directly + * + * @param string $checksum The checksum to add + * @param bool $inBinaryForm TRUE if checksum is in binary form + * + * @return self + * @throws \LogicException if the root tree hash is already calculated + */ + public function addChecksum($checksum, $inBinaryForm = false) + { + // Error if hash is already calculated + if ($this->hash) { + throw new \LogicException('You may not add more checksums to a ' + . 'complete tree hash.'); + } + + // Convert the checksum to binary form if necessary + $this->checksums[] = $inBinaryForm ? $checksum : hex2bin($checksum); + + return $this; + } + + public function complete() + { + if (!$this->hash) { + // Clear out the remaining buffer. + if (strlen($this->buffer) > 0) { + $this->checksums[] = hash($this->algorithm, $this->buffer, true); + $this->buffer = ''; + } + + // If no hashes, add the EMPTY_HASH. + if (!$this->checksums) { + $this->checksums[] = hex2bin(self::EMPTY_HASH); + } + + // Perform hashes up the tree to arrive at the root checksum. + $hashes = $this->checksums; + while (count($hashes) > 1) { + $sets = array_chunk($hashes, 2); + $hashes = array(); + foreach ($sets as $set) { + $hashes[] = (count($set) === 1) + ? $set[0] + : hash($this->algorithm, $set[0] . $set[1], true); + } + } + + $this->hash = $hashes[0]; + } + + return $this->hash; + } + + public function reset() + { + $this->hash = null; + $this->checksums = []; + $this->buffer = ''; + } +} |