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