68 lines
2.2 KiB
PHP
68 lines
2.2 KiB
PHP
<?php
|
|
// HashAlgorithm.php
|
|
// Created: 2021-06-16
|
|
// Updated: 2022-02-27
|
|
|
|
namespace Index\Security;
|
|
|
|
use HashContext;
|
|
use InvalidArgumentException;
|
|
use RuntimeException;
|
|
use Index\ICloneable;
|
|
use Index\IO\GenericStream;
|
|
|
|
class HashAlgorithm implements ICloneable {
|
|
private HashAlgorithmInfo $info;
|
|
private HashContext $context;
|
|
|
|
public function __construct(HashAlgorithmInfo $info, ?HashContext $context = null) {
|
|
$this->info = $info;
|
|
if($context === null)
|
|
$this->reset();
|
|
else
|
|
$this->context = $context;
|
|
}
|
|
|
|
public function reset(): void {
|
|
$this->context = hash_init($this->info->getName(), $this->info->isHMAC() ? HASH_HMAC : 0, $this->info->getKey());
|
|
}
|
|
|
|
public function update(string $data): void {
|
|
hash_update($this->context, $data);
|
|
}
|
|
|
|
public function updateStream(mixed $stream, int $length = -1): int {
|
|
if($stream instanceof GenericStream)
|
|
$stream = $stream->getResource();
|
|
if(!is_resource($stream))
|
|
throw new InvalidArgumentException('$stream must be a resource or an instance of Index\IO\GenericStream.');
|
|
return hash_update_stream($this->context, $stream, $length);
|
|
}
|
|
|
|
public function updateFile(string $fileName, mixed $streamContext = null): void {
|
|
if($streamContext !== null && !is_resource($streamContext))
|
|
throw new InvalidArgumentException('$streamContext must be null or a resource.');
|
|
if(!hash_update_file($this->context, $fileName, $streamContext))
|
|
throw new RuntimeException('File hash failed.');
|
|
}
|
|
|
|
public function finalise(bool $hex = false): string {
|
|
return hash_final($this->context, !$hex);
|
|
}
|
|
|
|
public function clone(): mixed {
|
|
return new HashAlgorithm($this->info, hash_copy($this->context));
|
|
}
|
|
|
|
public static function equals(
|
|
HashAlgorithm|string $trusted,
|
|
HashAlgorithm|string $foreign
|
|
): bool {
|
|
if($trusted instanceof HashAlgorithm)
|
|
$trusted = $trusted->finalise(false);
|
|
if($foreign instanceof HashAlgorithm)
|
|
$foreign = $foreign->finalise(false);
|
|
return hash_equals($trusted, $foreign);
|
|
}
|
|
}
|