/**
  * <p>Decodes given set of received codewords, which include both data and error-correction
  * codewords. Really, this means it uses Reed-Solomon to detect and correct errors, in-place,
  * in the input.</p>
  *
  * @param received data and error-correction codewords
  * @param twoS number of error-correction codewords available
  * @throws ReedSolomonException if decoding fails for any reason
  */
 public function decode(&$received, $twoS)
 {
     $poly = new GenericGFPoly($this->field, $received);
     $syndromeCoefficients = fill_array(0, $twoS, 0);
     $noError = true;
     for ($i = 0; $i < $twoS; $i++) {
         $eval = $poly->evaluateAt($this->field->exp($i + $this->field->getGeneratorBase()));
         $syndromeCoefficients[count($syndromeCoefficients) - 1 - $i] = $eval;
         if ($eval != 0) {
             $noError = false;
         }
     }
     if ($noError) {
         return;
     }
     $syndrome = new GenericGFPoly($this->field, $syndromeCoefficients);
     $sigmaOmega = $this->runEuclideanAlgorithm($this->field->buildMonomial($twoS, 1), $syndrome, $twoS);
     $sigma = $sigmaOmega[0];
     $omega = $sigmaOmega[1];
     $errorLocations = $this->findErrorLocations($sigma);
     $errorMagnitudes = $this->findErrorMagnitudes($omega, $errorLocations);
     for ($i = 0; $i < count($errorLocations); $i++) {
         $position = count($received) - 1 - $this->field->log($errorLocations[$i]);
         if ($position < 0) {
             throw new ReedSolomonException("Bad error location");
         }
         $received[$position] = GenericGF::addOrSubtract($received[$position], $errorMagnitudes[$i]);
     }
 }
        if ($a == 0) {
            throw new Exception();
        }
        return $this->expTable[$this->size - $this->logTable[$a] - 1];
    }
    /**
     * @return product of a and b in GF(size)
     */
    function multiply($a, $b)
    {
        if ($a == 0 || $b == 0) {
            return 0;
        }
        return $this->expTable[($this->logTable[$a] + $this->logTable[$b]) % ($this->size - 1)];
    }
    public function getSize()
    {
        return $this->size;
    }
    public function getGeneratorBase()
    {
        return $this->generatorBase;
    }
    // @Override
    public function toString()
    {
        return "GF(0x" . dechex(intval($this->primitive)) . ',' . $this->size . ')';
    }
}
GenericGF::Init();
Example #3
0
 public function multiply(GenericGFPoly $other)
 {
     if ($other->getField() != $this->field) {
         throw new \InvalidArgumentException('GenericGFPolys do not have same GenericGF field');
     }
     if ($this->isZero() || $other->isZero()) {
         return $this->field->getZero();
     }
     $aCoefficients = $this->getCoefficients();
     $aLength = count($aCoefficients);
     $bCoefficients = $other->getCoefficients();
     $bLength = count($bCoefficients);
     $product = array_fill(0, $aLength + $bLength - 1, 0);
     for ($i = 0; $i < $aLength; $i++) {
         $aCoeff = $aCoefficients[$i];
         for ($j = 0; $j < $bLength; $j++) {
             $product[$i + $j] = GenericGF::addOrSubtract($product[$i + $j], $this->field->multiply($aCoeff, $bCoefficients[$j]));
         }
     }
     return new self($this->field, $product);
 }