<?php
namespace ParagonIE\CipherSweet;
use ParagonIE\CipherSweet\Contract\TransformationInterface;
use ParagonIE\CipherSweet\Transformation\Compound;
/**
* Class CompoundIndex
* @package ParagonIE\CipherSweet
*/
class CompoundIndex
{
/**
* @var array<int, string> $columns
*/
protected $columns;
/**
* @var bool $fastHash
*/
protected $fastHash;
/**
* @var array $hashConfig
*/
protected $hashConfig;
/**
* @var string $name
*/
protected $name;
/**
* @var int $outputLength
*/
protected $filterBits = 256;
/**
* @var array<string, array<int, TransformationInterface>>
*/
protected $columnTransforms = [];
/**
* @var Compound
*/
private static $compounder;
/**
* CompoundIndex constructor.
*
* @param string $name
* @param array<int, string> $columns
* @param int $filterBits
* @param bool $fastHash
* @param array $hashConfig
*/
public function __construct(
$name,
array $columns = [],
$filterBits = 256,
$fastHash = false,
array $hashConfig = []
) {
$this->name = $name;
$this->columns = $columns;
$this->filterBits = $filterBits;
$this->fastHash = $fastHash;
$this->hashConfig = $hashConfig;
}
/**
* @return Compound
*/
public static function getCompounder()
{
if (!self::$compounder) {
self::$compounder = new Compound();
}
return self::$compounder;
}
/**
* @param string $column
* @param TransformationInterface $tf
* @return self
*/
public function addTransform($column, TransformationInterface $tf)
{
$this->columnTransforms[$column][] = $tf;
return $this;
}
/**
* @return array<int, string>
*/
public function getColumns()
{
return $this->columns;
}
/**
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* @return bool
*/
public function getFastHash()
{
return $this->fastHash;
}
/**
* @return int
*/
public function getFilterBitLength()
{
return $this->filterBits;
}
/**
* @return array
*/
public function getHashConfig()
{
return $this->hashConfig;
}
/**
* @param string $column
* @return array<int, TransformationInterface>
*/
public function getTransforms($column)
{
if (!\array_key_exists($column, $this->columns)) {
return [];
}
return $this->columnTransforms[$column];
}
/**
* Get a packed plaintext for use in creating a compound blind index
* This is a one-way transformation meant to be distinct from other inputs
* Not all elements of the row will be used.
*
* @param array $row
*
* @return string
* @throws \Exception
*/
public function getPacked(array $row)
{
/** @var array<int, string> $pieces */
$pieces = [];
/** @var string $col */
foreach ($this->columns as $col) {
if (!\array_key_exists($col, $row)) {
continue;
}
/** @var string $piece */
$piece = $row[$col];
if (!empty($this->columnTransforms[$col])) {
foreach ($this->columnTransforms[$col] as $tf) {
if ($tf instanceof TransformationInterface) {
/** @var string $piece */
$piece = $tf($piece);
}
}
}
$pieces[$col] = $piece;
}
$compounder = self::getCompounder();
return (string) $compounder($pieces);
}
}
|