diff --git a/src/common/reedsolomon/mod.rs b/src/common/reedsolomon/mod.rs
index f4d8d7e..cd46acc 100644
--- a/src/common/reedsolomon/mod.rs
+++ b/src/common/reedsolomon/mod.rs
@@ -57,14 +57,14 @@ impl ReedSolomonException {
//package com.google.zxing.common.reedsolomon;
-pub const AZTEC_DATA_12:GenericGF = GenericGF::new(0x1069, 4096, 1); // x^12 + x^6 + x^5 + x^3 + 1
-pub const AZTEC_DATA_10:GenericGF = GenericGF::new(0x409, 1024, 1); // x^10 + x^3 + 1
-pub const AZTEC_DATA_6:GenericGF = GenericGF::new(0x43, 64, 1); // x^6 + x + 1
-pub const AZTEC_PARAM:GenericGF = GenericGF::new(0x13, 16, 1); // x^4 + x + 1
-pub const QR_CODE_FIELD_256:GenericGF = GenericGF::new(0x011D, 256, 0); // x^8 + x^4 + x^3 + x^2 + 1
-pub const DATA_MATRIX_FIELD_256:GenericGF = GenericGF::new(0x012D, 256, 1); // x^8 + x^5 + x^3 + x^2 + 1
-pub const AZTEC_DATA_8:GenericGF = DATA_MATRIX_FIELD_256;
-pub const MAXICODE_FIELD_64:GenericGF = AZTEC_DATA_6;
+pub const AZTEC_DATA_12: GenericGF = GenericGF::new(0x1069, 4096, 1); // x^12 + x^6 + x^5 + x^3 + 1
+pub const AZTEC_DATA_10: GenericGF = GenericGF::new(0x409, 1024, 1); // x^10 + x^3 + 1
+pub const AZTEC_DATA_6: GenericGF = GenericGF::new(0x43, 64, 1); // x^6 + x + 1
+pub const AZTEC_PARAM: GenericGF = GenericGF::new(0x13, 16, 1); // x^4 + x + 1
+pub const QR_CODE_FIELD_256: GenericGF = GenericGF::new(0x011D, 256, 0); // x^8 + x^4 + x^3 + x^2 + 1
+pub const DATA_MATRIX_FIELD_256: GenericGF = GenericGF::new(0x012D, 256, 1); // x^8 + x^5 + x^3 + x^2 + 1
+pub const AZTEC_DATA_8: GenericGF = DATA_MATRIX_FIELD_256;
+pub const MAXICODE_FIELD_64: GenericGF = AZTEC_DATA_6;
/**
*
This class contains utility methods for performing mathematical operations over
@@ -77,158 +77,153 @@ pub const MAXICODE_FIELD_64:GenericGF = AZTEC_DATA_6;
* @author Sean Owen
* @author David Olivier
*/
- pub struct GenericGF {
-
- expTable : Vec,
+pub struct GenericGF {
+ expTable: Vec,
logTable: Vec,
zero: Box,
one: Box,
- size:usize,
- primitive:usize,
- generatorBase:usize,
+ size: usize,
+ primitive: usize,
+ generatorBase: usize,
}
impl Hash for GenericGF {
- fn hash(&self, state: &mut H) {
- self.to_string().hash(state);
- }
+ fn hash(&self, state: &mut H) {
+ self.to_string().hash(state);
+ }
}
impl PartialEq for GenericGF {
- fn eq(&self, other: &Self) -> bool {
- self.to_string() == other.to_string()
- }
+ fn eq(&self, other: &Self) -> bool {
+ self.to_string() == other.to_string()
+ }
}
impl Eq for GenericGF {}
-impl GenericGF{
+impl GenericGF {
+ /**
+ * Create a representation of GF(size) using the given primitive polynomial.
+ *
+ * @param primitive irreducible polynomial whose coefficients are represented by
+ * the bits of an int, where the least-significant bit represents the constant
+ * coefficient
+ * @param size the size of the field
+ * @param b the factor b in the generator polynomial can be 0- or 1-based
+ * (g(x) = (x+a^b)(x+a^(b+1))...(x+a^(b+2t-1))).
+ * In most cases it should be 1, but for QR code it is 0.
+ */
+ pub fn new(primitive: usize, size: usize, b: usize) -> Self {
+ let mut new_ggf: Self;
- /**
- * Create a representation of GF(size) using the given primitive polynomial.
- *
- * @param primitive irreducible polynomial whose coefficients are represented by
- * the bits of an int, where the least-significant bit represents the constant
- * coefficient
- * @param size the size of the field
- * @param b the factor b in the generator polynomial can be 0- or 1-based
- * (g(x) = (x+a^b)(x+a^(b+1))...(x+a^(b+2t-1))).
- * In most cases it should be 1, but for QR code it is 0.
- */
- pub fn new( primitive:usize, size:usize, b:usize) -> Self{
- let mut new_ggf :Self;
+ new_ggf.primitive = primitive;
+ new_ggf.size = size;
+ new_ggf.generatorBase = b;
+ new_ggf.expTable = Vec::with_capacity(size);
+ new_ggf.logTable = Vec::with_capacity(size);
+ let mut x = 1;
+ for i in 0..size {
+ //for (int i = 0; i < size; i++) {
+ new_ggf.expTable[i] = x;
+ x *= 2; // we're assuming the generator alpha is 2
+ if x >= size {
+ x ^= primitive;
+ x &= size - 1;
+ }
+ }
+ for i in 0..size {
+ //for (int i = 0; i < size - 1; i++) {
+ new_ggf.logTable[new_ggf.expTable[i]] = i;
+ }
- new_ggf. primitive = primitive;
- new_ggf. size = size;
- new_ggf. generatorBase = b;
+ // logTable[0] == 0 but this should never be used
+ new_ggf.zero = Box::new(GenericGFPoly::new(Box::new(new_ggf), &vec![0]).unwrap());
+ new_ggf.one = Box::new(GenericGFPoly::new(Box::new(new_ggf), &vec![1]).unwrap());
- new_ggf. expTable = Vec::with_capacity(size);
- new_ggf. logTable = Vec::with_capacity(size);
- let mut x = 1;
- for i in 0..size {
- //for (int i = 0; i < size; i++) {
- new_ggf.expTable[i] = x;
- x *= 2; // we're assuming the generator alpha is 2
- if x >= size {
- x ^= primitive;
- x &= size - 1;
- }
- }
- for i in 0..size {
- //for (int i = 0; i < size - 1; i++) {
- new_ggf.logTable[new_ggf.expTable[i]] = i;
+ new_ggf
}
- // logTable[0] == 0 but this should never be used
- new_ggf. zero = Box::new(GenericGFPoly::new(Box::new(new_ggf), &vec![0]).unwrap());
- new_ggf. one = Box::new(GenericGFPoly::new(Box::new(new_ggf), &vec![1]).unwrap());
-
- new_ggf
- }
-
- pub fn getZero(&self) -> Box{
- return self.zero;
- }
-
- pub fn getOne(&self) -> Box {
- return self.one;
- }
-
- /**
- * @return the monomial representing coefficient * x^degree
- */
- pub fn buildMonomial(&self, degree :usize, coefficient:usize) -> Box{
- if (coefficient == 0) {
- return self.zero;
+ pub fn getZero(&self) -> Box {
+ return self.zero;
}
- let coefficients = Vec::with_capacity(degree + 1);
- coefficients[0] = coefficient;
- return Box::new(GenericGFPoly::new(Box::new(*self), &coefficients).unwrap());
- }
- /**
- * Implements both addition and subtraction -- they are the same in GF(size).
- *
- * @return sum/difference of a and b
- */
- pub fn addOrSubtract( a:usize, b:usize) -> usize {
- return a ^ b;
- }
-
- /**
- * @return 2 to the power of a in GF(size)
- */
- pub fn exp(&self, a:usize) -> usize{
- return self.expTable[a];
- }
-
- /**
- * @return base 2 log of a in GF(size)
- */
- pub fn log(&self, a:usize) -> Result {
- if (a == 0) {
- return Err( IllegalArgumentException::new(""));
+ pub fn getOne(&self) -> Box {
+ return self.one;
}
- return Ok(self.logTable[a]);
- }
- /**
- * @return multiplicative inverse of a
- */
- pub fn inverse(&self, a:usize) -> Result{
- if (a == 0) {
- return Err( ArithmeticException::new(""));
+ /**
+ * @return the monomial representing coefficient * x^degree
+ */
+ pub fn buildMonomial(&self, degree: usize, coefficient: usize) -> Box {
+ if (coefficient == 0) {
+ return self.zero;
+ }
+ let coefficients = Vec::with_capacity(degree + 1);
+ coefficients[0] = coefficient;
+ return Box::new(GenericGFPoly::new(Box::new(*self), &coefficients).unwrap());
}
- let loc = self.size - self.logTable[a] - 1;
- return Ok(self.expTable[loc]);
- }
- /**
- * @return product of a and b in GF(size)
- */
- pub fn multiply(&self, a:usize, b:usize) -> usize {
- if (a == 0 || b == 0) {
- return 0;
+ /**
+ * Implements both addition and subtraction -- they are the same in GF(size).
+ *
+ * @return sum/difference of a and b
+ */
+ pub fn addOrSubtract(a: usize, b: usize) -> usize {
+ return a ^ b;
}
- return self.expTable[(self.logTable[a] + self.logTable[b]) % (self.size - 1)];
- }
- pub fn getSize(&self) -> usize{
- return self.size;
- }
+ /**
+ * @return 2 to the power of a in GF(size)
+ */
+ pub fn exp(&self, a: usize) -> usize {
+ return self.expTable[a];
+ }
- pub fn getGeneratorBase(&self) -> usize {
- return self.generatorBase;
- }
+ /**
+ * @return base 2 log of a in GF(size)
+ */
+ pub fn log(&self, a: usize) -> Result {
+ if (a == 0) {
+ return Err(IllegalArgumentException::new(""));
+ }
+ return Ok(self.logTable[a]);
+ }
+ /**
+ * @return multiplicative inverse of a
+ */
+ pub fn inverse(&self, a: usize) -> Result {
+ if (a == 0) {
+ return Err(ArithmeticException::new(""));
+ }
+ let loc = self.size - self.logTable[a] - 1;
+ return Ok(self.expTable[loc]);
+ }
+
+ /**
+ * @return product of a and b in GF(size)
+ */
+ pub fn multiply(&self, a: usize, b: usize) -> usize {
+ if (a == 0 || b == 0) {
+ return 0;
+ }
+ return self.expTable[(self.logTable[a] + self.logTable[b]) % (self.size - 1)];
+ }
+
+ pub fn getSize(&self) -> usize {
+ return self.size;
+ }
+
+ pub fn getGeneratorBase(&self) -> usize {
+ return self.generatorBase;
+ }
}
impl fmt::Display for GenericGF {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(f,"GF({:#06x},{}" ,self.primitive , self.size )
+ write!(f, "GF({:#06x},{}", self.primitive, self.size)
}
}
-
/*
* Copyright 2007 ZXing authors
*
@@ -257,275 +252,315 @@ impl fmt::Display for GenericGF {
* @author Sean Owen
*/
pub struct GenericGFPoly {
-
field: Box,
coefficients: Vec,
-
}
impl GenericGFPoly {
- /**
- * @param field the {@link GenericGF} instance representing the field to use
- * to perform computations
- * @param coefficients coefficients as ints representing elements of GF(size), arranged
- * from most significant (highest-power term) coefficient to least significant
- * @throws IllegalArgumentException if argument is null or empty,
- * or if leading coefficient is 0 and this is not a
- * constant polynomial (that is, it is not the monomial "0")
- */
- pub fn new( field :Box, coefficients: &Vec) -> Result {
- if (coefficients.len() == 0) {
- return Err (IllegalArgumentException::new(""));
+ /**
+ * @param field the {@link GenericGF} instance representing the field to use
+ * to perform computations
+ * @param coefficients coefficients as ints representing elements of GF(size), arranged
+ * from most significant (highest-power term) coefficient to least significant
+ * @throws IllegalArgumentException if argument is null or empty,
+ * or if leading coefficient is 0 and this is not a
+ * constant polynomial (that is, it is not the monomial "0")
+ */
+ pub fn new(
+ field: Box,
+ coefficients: &Vec,
+ ) -> Result {
+ if (coefficients.len() == 0) {
+ return Err(IllegalArgumentException::new(""));
+ }
+ Ok(Self {
+ field: field,
+ coefficients: {
+ let coefficientsLength = coefficients.len();
+ if (coefficientsLength > 1 && coefficients[0] == 0) {
+ // Leading term must be non-zero for anything except the constant polynomial "0"
+ let mut firstNonZero = 1;
+ while (firstNonZero < coefficientsLength && coefficients[firstNonZero] == 0) {
+ firstNonZero += 1;
+ }
+ if (firstNonZero == coefficientsLength) {
+ vec![0]
+ } else {
+ let mut new_coefficients =
+ Vec::with_capacity(coefficientsLength - firstNonZero);
+ new_coefficients[0..new_coefficients.len()]
+ .clone_from_slice(&coefficients[firstNonZero..new_coefficients.len()]);
+ // System.arraycopy(coefficients,
+ // firstNonZero,
+ // this.coefficients,
+ // 0,
+ // this.coefficients.length);
+ new_coefficients
+ }
+ } else {
+ coefficients.to_vec()
+ }
+ },
+ })
}
- Ok(Self{
- field: field,
- coefficients: {
- let coefficientsLength = coefficients.len();
- if (coefficientsLength > 1 && coefficients[0] == 0) {
- // Leading term must be non-zero for anything except the constant polynomial "0"
- let mut firstNonZero = 1;
- while (firstNonZero < coefficientsLength && coefficients[firstNonZero] == 0) {
- firstNonZero += 1;
+
+ pub fn getCoefficients(&self) -> Vec {
+ return self.coefficients;
+ }
+
+ /**
+ * @return degree of this polynomial
+ */
+ pub fn getDegree(&self) -> usize {
+ return self.coefficients.len() - 1;
+ }
+
+ /**
+ * @return true iff this polynomial is the monomial "0"
+ */
+ pub fn isZero(&self) -> bool {
+ return self.coefficients[0] == 0;
+ }
+
+ /**
+ * @return coefficient of x^degree term in this polynomial
+ */
+ pub fn getCoefficient(&self, degree: usize) -> usize {
+ return self.coefficients[self.coefficients.len() - 1 - degree];
+ }
+
+ /**
+ * @return evaluation of this polynomial at a given point
+ */
+ pub fn evaluateAt(&self, a: usize) -> usize {
+ if (a == 0) {
+ // Just return the x^0 coefficient
+ return self.getCoefficient(0);
+ }
+ if (a == 1) {
+ // Just the sum of the coefficients
+ let mut result = 0;
+ for coefficient in self.coefficients {
+ //for (int coefficient : coefficients) {
+ result = GenericGF::addOrSubtract(result, coefficient);
}
- if (firstNonZero == coefficientsLength) {
- vec![0]
- } else {
-
- let mut new_coefficients = Vec::with_capacity(coefficientsLength - firstNonZero);
- new_coefficients[0..new_coefficients.len()].clone_from_slice(&coefficients[firstNonZero..new_coefficients.len()]);
- // System.arraycopy(coefficients,
- // firstNonZero,
- // this.coefficients,
- // 0,
- // this.coefficients.length);
- new_coefficients
+ return result;
+ }
+ let mut result = self.coefficients[0];
+ let size = self.coefficients.len();
+ for i in 1..size {
+ //for (int i = 1; i < size; i++) {
+ result = GenericGF::addOrSubtract(
+ self.field
+ .multiply(a, result.try_into().unwrap())
+ .try_into()
+ .unwrap(),
+ self.coefficients[i],
+ );
+ }
+ return result;
+ }
+
+ pub fn addOrSubtract(
+ &self,
+ other: Box,
+ ) -> Result, IllegalArgumentException> {
+ if self.field != other.field {
+ return Err(IllegalArgumentException::new(
+ "GenericGFPolys do not have same GenericGF field",
+ ));
+ }
+ if (self.isZero()) {
+ return Ok(other);
+ }
+ if (other.isZero()) {
+ return Ok(Box::new(*self));
+ }
+
+ let mut smallerCoefficients = self.coefficients;
+ let mut largerCoefficients = other.coefficients;
+ if (smallerCoefficients.len() > largerCoefficients.len()) {
+ let temp = smallerCoefficients;
+ smallerCoefficients = largerCoefficients;
+ largerCoefficients = temp;
+ }
+
+ let mut sumDiff = Vec::with_capacity(largerCoefficients.len());
+ let lengthDiff = largerCoefficients.len() - smallerCoefficients.len();
+ // Copy high-order terms only found in higher-degree polynomial's coefficients
+ sumDiff[0..lengthDiff].clone_from_slice(&largerCoefficients[0..lengthDiff]);
+ //System.arraycopy(largerCoefficients, 0, sumDiff, 0, lengthDiff);
+
+ for i in lengthDiff..largerCoefficients.len() {
+ //for (int i = lengthDiff; i < largerCoefficients.length; i++) {
+ sumDiff[i] = GenericGF::addOrSubtract(
+ smallerCoefficients[i - lengthDiff],
+ largerCoefficients[i],
+ );
+ }
+
+ return Ok(Box::new(GenericGFPoly::new(self.field, &sumDiff)?));
+ }
+
+ pub fn multiply(
+ &self,
+ other: &GenericGFPoly,
+ ) -> Result, IllegalArgumentException> {
+ if self.field != other.field {
+ //if (!field.equals(other.field)) {
+ return Err(IllegalArgumentException::new(
+ "GenericGFPolys do not have same GenericGF field",
+ ));
+ }
+ if (self.isZero() || other.isZero()) {
+ return Ok(self.field.getZero());
+ }
+ let aCoefficients = self.coefficients;
+ let aLength = aCoefficients.len();
+ let bCoefficients = other.coefficients;
+ let bLength = bCoefficients.len();
+ let product = Vec::with_capacity(aLength + bLength - 1);
+ for i in 0..aLength {
+ //for (int i = 0; i < aLength; i++) {
+ let aCoeff = aCoefficients[i];
+ for j in 0..bLength {
+ //for (int j = 0; j < bLength; j++) {
+ product[i + j] = GenericGF::addOrSubtract(
+ product[i + j],
+ self.field
+ .multiply(
+ aCoeff.try_into().unwrap(),
+ bCoefficients[j].try_into().unwrap(),
+ )
+ .try_into()
+ .unwrap(),
+ );
}
- } else {
- coefficients.to_vec()
- }
- },
- })
- }
-
- pub fn getCoefficients(&self)->Vec {
- return self.coefficients;
- }
-
- /**
- * @return degree of this polynomial
- */
- pub fn getDegree(&self) -> usize {
- return self.coefficients.len() - 1;
- }
-
- /**
- * @return true iff this polynomial is the monomial "0"
- */
- pub fn isZero(&self) -> bool{
- return self.coefficients[0] == 0;
- }
-
- /**
- * @return coefficient of x^degree term in this polynomial
- */
- pub fn getCoefficient(&self, degree:usize) -> usize {
- return self.coefficients[self.coefficients.len() - 1 - degree];
- }
-
- /**
- * @return evaluation of this polynomial at a given point
- */
- pub fn evaluateAt(&self, a:usize) -> usize {
- if (a == 0) {
- // Just return the x^0 coefficient
- return self.getCoefficient(0);
- }
- if (a == 1) {
- // Just the sum of the coefficients
- let mut result = 0;
- for coefficient in self.coefficients {
- //for (int coefficient : coefficients) {
- result = GenericGF::addOrSubtract(result, coefficient);
- }
- return result;
- }
- let mut result = self.coefficients[0];
- let size = self.coefficients.len();
- for i in 1..size {
- //for (int i = 1; i < size; i++) {
- result = GenericGF::addOrSubtract(self.field.multiply(a, result.try_into().unwrap()).try_into().unwrap(), self.coefficients[i]);
- }
- return result;
- }
-
- pub fn addOrSubtract(&self, other:Box) -> Result,IllegalArgumentException>{
- if self.field != other.field {
- return Err(IllegalArgumentException::new("GenericGFPolys do not have same GenericGF field"));
- }
- if (self.isZero()) {
- return Ok(other);
- }
- if (other.isZero()) {
- return Ok(Box::new(*self));
+ }
+ return Ok(Box::new(GenericGFPoly::new(self.field, &product)?));
}
- let mut smallerCoefficients = self.coefficients;
- let mut largerCoefficients = other.coefficients;
- if (smallerCoefficients.len() > largerCoefficients.len()) {
- let temp = smallerCoefficients;
- smallerCoefficients = largerCoefficients;
- largerCoefficients = temp;
- }
-
- let mut sumDiff = Vec::with_capacity(largerCoefficients.len());
- let lengthDiff = largerCoefficients.len() - smallerCoefficients.len();
- // Copy high-order terms only found in higher-degree polynomial's coefficients
- sumDiff[0..lengthDiff].clone_from_slice(&largerCoefficients[0..lengthDiff]);
- //System.arraycopy(largerCoefficients, 0, sumDiff, 0, lengthDiff);
+ pub fn multiply_with_scalar(&self, scalar: usize) -> Box {
+ if (scalar == 0) {
+ return self.field.getZero();
+ }
+ if (scalar == 1) {
+ return Box::new(*self);
+ }
+ let size = self.coefficients.len();
- for i in lengthDiff..largerCoefficients.len(){
- //for (int i = lengthDiff; i < largerCoefficients.length; i++) {
- sumDiff[i] = GenericGF::addOrSubtract(smallerCoefficients[i - lengthDiff], largerCoefficients[i]);
+ let product = Vec::with_capacity(size);
+ for i in 0..size {
+ //for (int i = 0; i < size; i++) {
+ product[i] = self.field.multiply(self.coefficients[i], scalar);
+ }
+ return Box::new(GenericGFPoly::new(self.field, &product).unwrap());
}
- return Ok(Box::new(GenericGFPoly::new(self.field, &sumDiff)?));
- }
-
- pub fn multiply(&self, other:&GenericGFPoly) -> Result,IllegalArgumentException> {
- if self.field != other.field{
- //if (!field.equals(other.field)) {
- return Err( IllegalArgumentException::new("GenericGFPolys do not have same GenericGF field"));
- }
- if (self.isZero() || other.isZero()) {
- return Ok(self.field.getZero());
- }
- let aCoefficients = self.coefficients;
- let aLength = aCoefficients.len();
- let bCoefficients = other.coefficients;
- let bLength = bCoefficients.len();
- let product = Vec::with_capacity(aLength + bLength - 1);
- for i in 0 ..aLength {
- //for (int i = 0; i < aLength; i++) {
- let aCoeff = aCoefficients[i];
- for j in 0..bLength {
- //for (int j = 0; j < bLength; j++) {
- product[i + j] = GenericGF::addOrSubtract(product[i + j],
- self.field.multiply(aCoeff.try_into().unwrap(), bCoefficients[j].try_into().unwrap()).try_into().unwrap());
- }
- }
- return Ok(Box::new(GenericGFPoly::new(self.field, &product)?));
- }
-
- pub fn multiply_with_scalar(&self, scalar:usize) -> Box{
- if (scalar == 0) {
- return self.field.getZero();
- }
- if (scalar == 1) {
- return Box::new(*self);
- }
- let size = self.coefficients.len();
-
- let product = Vec::with_capacity(size);
- for i in 0..size {
- //for (int i = 0; i < size; i++) {
- product[i] = self.field.multiply(self.coefficients[i], scalar);
- }
- return Box::new(GenericGFPoly::new(self.field, &product).unwrap());
- }
-
- pub fn multiplyByMonomial(&self, degree:usize, coefficient:usize) -> Result,IllegalArgumentException> {
- if (degree < 0) {
- return Err( IllegalArgumentException::new(""));
- }
- if (coefficient == 0) {
- return Ok(self.field.getZero());
- }
- let size = self.coefficients.len();
- let product = Vec::with_capacity(size + degree);
- for i in 0..size {
- //for (int i = 0; i < size; i++) {
- product[i] = self.field.multiply(self.coefficients[i], coefficient);
- }
- return Ok(Box::new(GenericGFPoly::new(self.field, &product)?));
- }
-
- pub fn divide(&self, other:&GenericGFPoly) -> Result>,IllegalArgumentException>{
- if self.field != other.field {
- //if (!field.equals(other.field)) {
- return Err( IllegalArgumentException::new("GenericGFPolys do not have same GenericGF field"));
- }
- if (other.isZero()) {
- return Err( IllegalArgumentException::new("Divide by 0"));
+ pub fn multiplyByMonomial(
+ &self,
+ degree: usize,
+ coefficient: usize,
+ ) -> Result, IllegalArgumentException> {
+ if (degree < 0) {
+ return Err(IllegalArgumentException::new(""));
+ }
+ if (coefficient == 0) {
+ return Ok(self.field.getZero());
+ }
+ let size = self.coefficients.len();
+ let product = Vec::with_capacity(size + degree);
+ for i in 0..size {
+ //for (int i = 0; i < size; i++) {
+ product[i] = self.field.multiply(self.coefficients[i], coefficient);
+ }
+ return Ok(Box::new(GenericGFPoly::new(self.field, &product)?));
}
- let mut quotient = self.field.getZero();
- let mut remainder = self;
+ pub fn divide(
+ &self,
+ other: &GenericGFPoly,
+ ) -> Result>, IllegalArgumentException> {
+ if self.field != other.field {
+ //if (!field.equals(other.field)) {
+ return Err(IllegalArgumentException::new(
+ "GenericGFPolys do not have same GenericGF field",
+ ));
+ }
+ if (other.isZero()) {
+ return Err(IllegalArgumentException::new("Divide by 0"));
+ }
- let denominatorLeadingTerm = other.getCoefficient(other.getDegree());
- let inverseDenominatorLeadingTerm = match self.field.inverse(denominatorLeadingTerm){
- Ok(val) => val,
- Err(issue) => return Err(IllegalArgumentException::new("arithmetic issue")),
- };
+ let mut quotient = self.field.getZero();
+ let mut remainder = self;
- while (remainder.getDegree() >= other.getDegree() && !remainder.isZero()) {
- let degreeDifference = remainder.getDegree() - other.getDegree();
- let scale = self.field.multiply(remainder.getCoefficient(remainder.getDegree()), inverseDenominatorLeadingTerm);
- let term = other.multiplyByMonomial(degreeDifference, scale)?;
- let iterationQuotient = self.field.buildMonomial(degreeDifference, scale);
- quotient = quotient.addOrSubtract(iterationQuotient)?;
- remainder = &*remainder.addOrSubtract(term)?;
+ let denominatorLeadingTerm = other.getCoefficient(other.getDegree());
+ let inverseDenominatorLeadingTerm = match self.field.inverse(denominatorLeadingTerm) {
+ Ok(val) => val,
+ Err(issue) => return Err(IllegalArgumentException::new("arithmetic issue")),
+ };
+
+ while (remainder.getDegree() >= other.getDegree() && !remainder.isZero()) {
+ let degreeDifference = remainder.getDegree() - other.getDegree();
+ let scale = self.field.multiply(
+ remainder.getCoefficient(remainder.getDegree()),
+ inverseDenominatorLeadingTerm,
+ );
+ let term = other.multiplyByMonomial(degreeDifference, scale)?;
+ let iterationQuotient = self.field.buildMonomial(degreeDifference, scale);
+ quotient = quotient.addOrSubtract(iterationQuotient)?;
+ remainder = &*remainder.addOrSubtract(term)?;
+ }
+
+ return Ok(vec![quotient, Box::new(*remainder)]);
}
-
- return Ok(vec! [ quotient, Box::new(*remainder) ]);
- }
-
}
impl fmt::Display for GenericGFPoly {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- if (self.isZero()) {
- return write!(f,"0");
- }
- let result = String::with_capacity(8 * self.getDegree());
- for degree in (0..self.getDegree()).rev(){
- //for (int degree = getDegree(); degree >= 0; degree--) {
- let coefficient = self.getCoefficient(degree);
- if (coefficient != 0) {
- if (coefficient < 0) {
- if (degree == self.getDegree()) {
- result.push_str("-");
- } else {
- result.push_str(" - ");
- }
- //coefficient = -coefficient;
- todo!("probably coefficient should be unsigned but what a mess");
- } else {
- if (result.len() > 0) {
- result.push_str(" + ");
- }
- }
- if (degree == 0 || coefficient != 1) {
- let alphaPower = self.field.log(coefficient);
- if (alphaPower.unwrap() == 0) {
- result.push_str("1");
- } else if (alphaPower.unwrap() == 1) {
- result.push_str("a");
- } else {
- result.push_str("a^");
- result.push_str(&format!("{}",alphaPower.unwrap()));
- }
- }
- if (degree != 0) {
- if (degree == 1) {
- result.push_str("x");
- } else {
- result.push_str("x^");
- result.push_str(&format!("{}",degree));
- }
- }
+ if (self.isZero()) {
+ return write!(f, "0");
}
- }
- write!(f,"{}", result)
+ let result = String::with_capacity(8 * self.getDegree());
+ for degree in (0..self.getDegree()).rev() {
+ //for (int degree = getDegree(); degree >= 0; degree--) {
+ let coefficient = self.getCoefficient(degree);
+ if (coefficient != 0) {
+ if (coefficient < 0) {
+ if (degree == self.getDegree()) {
+ result.push_str("-");
+ } else {
+ result.push_str(" - ");
+ }
+ //coefficient = -coefficient;
+ todo!("probably coefficient should be unsigned but what a mess");
+ } else {
+ if (result.len() > 0) {
+ result.push_str(" + ");
+ }
+ }
+ if (degree == 0 || coefficient != 1) {
+ let alphaPower = self.field.log(coefficient);
+ if (alphaPower.unwrap() == 0) {
+ result.push_str("1");
+ } else if (alphaPower.unwrap() == 1) {
+ result.push_str("a");
+ } else {
+ result.push_str("a^");
+ result.push_str(&format!("{}", alphaPower.unwrap()));
+ }
+ }
+ if (degree != 0) {
+ if (degree == 1) {
+ result.push_str("x");
+ } else {
+ result.push_str("x^");
+ result.push_str(&format!("{}", degree));
+ }
+ }
+ }
+ }
+ write!(f, "{}", result)
}
}
/*
@@ -569,199 +604,233 @@ impl fmt::Display for GenericGFPoly {
* @author sanfordsquires
*/
pub struct ReedSolomonDecoder {
-
- field: Box,
-
+ field: Box,
}
-impl ReedSolomonDecoder{
- pub fn new ( field: GenericGF) -> Self {
- Self { field: Box::new(field) }
- }
-
- /**
- * 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.
- *
- * @param received data and error-correction codewords
- * @param twoS number of error-correction codewords available
- * @throws ReedSolomonException if decoding fails for any reason
- */
- pub fn decode( &self,received: &mut Vec, twoS:usize) -> Result<(),ReedSolomonException> {
- let poly = GenericGFPoly::new(self.field, received);
- let syndromeCoefficients = Vec::with_capacity(twoS);
- let mut noError = true;
- for i in 0..twoS {
- //for (int i = 0; i < twoS; i++) {
- let eval = poly.unwrap().evaluateAt(self.field.exp(i + self.field.getGeneratorBase()));
- syndromeCoefficients[syndromeCoefficients.len() - 1 - i] = eval;
- if (eval != 0) {
- noError = false;
- }
- }
- if (noError) {
- return Ok(());
- }
- let syndrome = match GenericGFPoly::new(self.field, &syndromeCoefficients) {
- Ok(res) => res,
- Err(fail) => return Err(ReedSolomonException::new("IllegalArgumentException"))
- };
- let sigmaOmega =
- self.runEuclideanAlgorithm(self.field.buildMonomial(twoS, 1), Box::new(syndrome), twoS);
- let sigma = sigmaOmega?[0];
- let omega = sigmaOmega?[1];
- let errorLocations = self.findErrorLocations(&sigma)?;
- let errorMagnitudes = self.findErrorMagnitudes(&omega, &errorLocations);
- for i in 0..errorLocations.len() {
- //for (int i = 0; i < errorLocations.length; i++) {
- let position = received.len() - 1 - match self.field.log(errorLocations[i]) {
- Ok(size) => size,
- Err(err) => return Err(ReedSolomonException::new("IllegalArgumentException"))
- };
- if (position < 0) {
- return Err(ReedSolomonException::new("Bad error location"));
- }
- received[position] = GenericGF::addOrSubtract(received[position], errorMagnitudes[i]);
- }
- Ok(())
- }
-
- fn runEuclideanAlgorithm(&self, a: Box, b:Box, R:usize)
- -> Result, ReedSolomonException> {
- // Assume a's degree is >= b's
- if (a.getDegree() < b.getDegree()) {
- let temp = a;
- a = b;
- b = temp;
- }
-
- let rLast = a;
- let r = b;
- let tLast = self.field.getZero();
- let t = self.field.getOne();
-
- // Run Euclidean algorithm until r's degree is less than R/2
- while (2 * r.getDegree() >= R) {
- let rLastLast = rLast;
- let tLastLast = tLast;
- rLast = r;
- tLast = t;
-
- // Divide rLastLast by rLast, with quotient in q and remainder in r
- if (rLast.isZero()) {
- // Oops, Euclidean algorithm already terminated?
- return Err( ReedSolomonException::new("r_{i-1} was zero"));
- }
- r = rLastLast;
- let q = self.field.getZero();
- let denominatorLeadingTerm = rLast.getCoefficient(rLast.getDegree());
- let dltInverse = match self.field.inverse(denominatorLeadingTerm){
- Ok(inv) => inv,
- Err(err) => return Err(ReedSolomonException::new("ArithmetricException")),
- };
- while (r.getDegree() >= rLast.getDegree() && !r.isZero()) {
- let degreeDiff = r.getDegree() - rLast.getDegree();
- let scale = self.field.multiply(r.getCoefficient(r.getDegree()), dltInverse);
- q = match q.addOrSubtract(self.field.buildMonomial(degreeDiff, scale)) {
- Ok(res) => res,
- Err(err) => return Err(ReedSolomonException::new("IllegalArgumentException")),
- };
- r = match r.addOrSubtract(match rLast.multiplyByMonomial(degreeDiff, scale)
- {
-Ok(res) => res,
-Err(err) => return Err(ReedSolomonException::new("IllegalArgumentException")),
- }){
- Ok(res)=> res,
- Err(err) => return Err(ReedSolomonException::new("IllegalArgumentException"))
- };
- }
-
- t = match (match q.multiply(&tLast){
-Ok(res) => res,
-Err(err) => return Err(ReedSolomonException::new("IllegalArgumentException")),
- }).addOrSubtract(tLastLast){
- Ok(res) => res,
- Err(err) => return Err(ReedSolomonException::new("IllegalArgumentException")),
- };
-
- if (r.getDegree() >= rLast.getDegree()) {
- return Err( ReedSolomonException::new(&format!("Division algorithm failed to reduce polynomial? r: {}, rLast: {}" ,r, rLast)));
- }
- }
-
- let sigmaTildeAtZero = t.getCoefficient(0);
- if (sigmaTildeAtZero == 0) {
- return Err( ReedSolomonException::new("sigmaTilde(0) was zero"));
- }
-
- let inverse = match self.field.inverse(sigmaTildeAtZero) {
-Ok(res) => res,
-Err(err) => return Err(ReedSolomonException::new("ArithmetricException")),
- };
- let sigma = t.multiply_with_scalar(inverse);
- let omega = r.multiply_with_scalar(inverse);
- return Ok(vec![*sigma, *omega]);
- }
-
- fn findErrorLocations(&self, errorLocator:&GenericGFPoly) -> Result, ReedSolomonException> {
- // This is a direct application of Chien's search
- let numErrors = errorLocator.getDegree();
- if (numErrors == 1) { // shortcut
- return Ok(vec![ errorLocator.getCoefficient(1) ]);
- }
-
- let result = Vec::with_capacity(numErrors);
- let mut e = 0;
- for i in 1..self.field.getSize() {
- //for (int i = 1; i < field.getSize() && e < numErrors; i++) {
- if e < numErrors { break; }
- if (errorLocator.evaluateAt(i) == 0) {
- result[e] = match self.field.inverse(i) {
-Ok(res)=>res,
-Err(err) => return Err(ReedSolomonException::new("ArithmetricException")),
- };
- e+=1;
- }
- }
- if (e != numErrors) {
- return Err( ReedSolomonException::new("Error locator degree does not match number of roots"));
- }
- return Ok(result);
- }
-
- fn findErrorMagnitudes( &self,errorEvaluator:&GenericGFPoly, errorLocations:&Vec) -> Vec {
- // This is directly applying Forney's Formula
- let s = errorLocations.len();
- let result = Vec::with_capacity(s);
- for i in 0..s {
- //for (int i = 0; i < s; i++) {
- let xiInverse = self.field.inverse(errorLocations[i]);
- let denominator = 1;
- for j in 0..s{
- //for (int j = 0; j < s; j++) {
- if (i != j) {
- //denominator = field.multiply(denominator,
- // GenericGF.addOrSubtract(1, field.multiply(errorLocations[j], xiInverse)));
- // Above should work but fails on some Apple and Linux JDKs due to a Hotspot bug.
- // Below is a funny-looking workaround from Steven Parkes
- let term =self. field.multiply(errorLocations[j], xiInverse.unwrap());
- let termPlus1 = if (term & 0x1) == 0 { term | 1} else { term & !1};
- denominator = self.field.multiply(denominator, termPlus1);
+impl ReedSolomonDecoder {
+ pub fn new(field: GenericGF) -> Self {
+ Self {
+ field: Box::new(field),
}
- }
- result[i] = self.field.multiply(errorEvaluator.evaluateAt(xiInverse.unwrap()),
- self.field.inverse(denominator).unwrap());
- if (self.field.getGeneratorBase() != 0) {
- result[i] = self.field.multiply(result[i], xiInverse.unwrap());
- }
}
- return result;
- }
+ /**
+ * 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.
+ *
+ * @param received data and error-correction codewords
+ * @param twoS number of error-correction codewords available
+ * @throws ReedSolomonException if decoding fails for any reason
+ */
+ pub fn decode(
+ &self,
+ received: &mut Vec,
+ twoS: usize,
+ ) -> Result<(), ReedSolomonException> {
+ let poly = GenericGFPoly::new(self.field, received);
+ let syndromeCoefficients = Vec::with_capacity(twoS);
+ let mut noError = true;
+ for i in 0..twoS {
+ //for (int i = 0; i < twoS; i++) {
+ let eval = poly
+ .unwrap()
+ .evaluateAt(self.field.exp(i + self.field.getGeneratorBase()));
+ syndromeCoefficients[syndromeCoefficients.len() - 1 - i] = eval;
+ if (eval != 0) {
+ noError = false;
+ }
+ }
+ if (noError) {
+ return Ok(());
+ }
+ let syndrome = match GenericGFPoly::new(self.field, &syndromeCoefficients) {
+ Ok(res) => res,
+ Err(fail) => return Err(ReedSolomonException::new("IllegalArgumentException")),
+ };
+ let sigmaOmega =
+ self.runEuclideanAlgorithm(self.field.buildMonomial(twoS, 1), Box::new(syndrome), twoS);
+ let sigma = sigmaOmega?[0];
+ let omega = sigmaOmega?[1];
+ let errorLocations = self.findErrorLocations(&sigma)?;
+ let errorMagnitudes = self.findErrorMagnitudes(&omega, &errorLocations);
+ for i in 0..errorLocations.len() {
+ //for (int i = 0; i < errorLocations.length; i++) {
+ let position = received.len()
+ - 1
+ - match self.field.log(errorLocations[i]) {
+ Ok(size) => size,
+ Err(err) => return Err(ReedSolomonException::new("IllegalArgumentException")),
+ };
+ if (position < 0) {
+ return Err(ReedSolomonException::new("Bad error location"));
+ }
+ received[position] = GenericGF::addOrSubtract(received[position], errorMagnitudes[i]);
+ }
+ Ok(())
+ }
+
+ fn runEuclideanAlgorithm(
+ &self,
+ a: Box,
+ b: Box,
+ R: usize,
+ ) -> Result, ReedSolomonException> {
+ // Assume a's degree is >= b's
+ if (a.getDegree() < b.getDegree()) {
+ let temp = a;
+ a = b;
+ b = temp;
+ }
+
+ let rLast = a;
+ let r = b;
+ let tLast = self.field.getZero();
+ let t = self.field.getOne();
+
+ // Run Euclidean algorithm until r's degree is less than R/2
+ while (2 * r.getDegree() >= R) {
+ let rLastLast = rLast;
+ let tLastLast = tLast;
+ rLast = r;
+ tLast = t;
+
+ // Divide rLastLast by rLast, with quotient in q and remainder in r
+ if (rLast.isZero()) {
+ // Oops, Euclidean algorithm already terminated?
+ return Err(ReedSolomonException::new("r_{i-1} was zero"));
+ }
+ r = rLastLast;
+ let q = self.field.getZero();
+ let denominatorLeadingTerm = rLast.getCoefficient(rLast.getDegree());
+ let dltInverse = match self.field.inverse(denominatorLeadingTerm) {
+ Ok(inv) => inv,
+ Err(err) => return Err(ReedSolomonException::new("ArithmetricException")),
+ };
+ while (r.getDegree() >= rLast.getDegree() && !r.isZero()) {
+ let degreeDiff = r.getDegree() - rLast.getDegree();
+ let scale = self
+ .field
+ .multiply(r.getCoefficient(r.getDegree()), dltInverse);
+ q = match q.addOrSubtract(self.field.buildMonomial(degreeDiff, scale)) {
+ Ok(res) => res,
+ Err(err) => return Err(ReedSolomonException::new("IllegalArgumentException")),
+ };
+ r = match r.addOrSubtract(match rLast.multiplyByMonomial(degreeDiff, scale) {
+ Ok(res) => res,
+ Err(err) => return Err(ReedSolomonException::new("IllegalArgumentException")),
+ }) {
+ Ok(res) => res,
+ Err(err) => return Err(ReedSolomonException::new("IllegalArgumentException")),
+ };
+ }
+
+ t = match (match q.multiply(&tLast) {
+ Ok(res) => res,
+ Err(err) => return Err(ReedSolomonException::new("IllegalArgumentException")),
+ })
+ .addOrSubtract(tLastLast)
+ {
+ Ok(res) => res,
+ Err(err) => return Err(ReedSolomonException::new("IllegalArgumentException")),
+ };
+
+ if (r.getDegree() >= rLast.getDegree()) {
+ return Err(ReedSolomonException::new(&format!(
+ "Division algorithm failed to reduce polynomial? r: {}, rLast: {}",
+ r, rLast
+ )));
+ }
+ }
+
+ let sigmaTildeAtZero = t.getCoefficient(0);
+ if (sigmaTildeAtZero == 0) {
+ return Err(ReedSolomonException::new("sigmaTilde(0) was zero"));
+ }
+
+ let inverse = match self.field.inverse(sigmaTildeAtZero) {
+ Ok(res) => res,
+ Err(err) => return Err(ReedSolomonException::new("ArithmetricException")),
+ };
+ let sigma = t.multiply_with_scalar(inverse);
+ let omega = r.multiply_with_scalar(inverse);
+ return Ok(vec![*sigma, *omega]);
+ }
+
+ fn findErrorLocations(
+ &self,
+ errorLocator: &GenericGFPoly,
+ ) -> Result, ReedSolomonException> {
+ // This is a direct application of Chien's search
+ let numErrors = errorLocator.getDegree();
+ if (numErrors == 1) {
+ // shortcut
+ return Ok(vec![errorLocator.getCoefficient(1)]);
+ }
+
+ let result = Vec::with_capacity(numErrors);
+ let mut e = 0;
+ for i in 1..self.field.getSize() {
+ //for (int i = 1; i < field.getSize() && e < numErrors; i++) {
+ if e < numErrors {
+ break;
+ }
+ if (errorLocator.evaluateAt(i) == 0) {
+ result[e] = match self.field.inverse(i) {
+ Ok(res) => res,
+ Err(err) => return Err(ReedSolomonException::new("ArithmetricException")),
+ };
+ e += 1;
+ }
+ }
+ if (e != numErrors) {
+ return Err(ReedSolomonException::new(
+ "Error locator degree does not match number of roots",
+ ));
+ }
+ return Ok(result);
+ }
+
+ fn findErrorMagnitudes(
+ &self,
+ errorEvaluator: &GenericGFPoly,
+ errorLocations: &Vec,
+ ) -> Vec {
+ // This is directly applying Forney's Formula
+ let s = errorLocations.len();
+ let result = Vec::with_capacity(s);
+ for i in 0..s {
+ //for (int i = 0; i < s; i++) {
+ let xiInverse = self.field.inverse(errorLocations[i]);
+ let denominator = 1;
+ for j in 0..s {
+ //for (int j = 0; j < s; j++) {
+ if (i != j) {
+ //denominator = field.multiply(denominator,
+ // GenericGF.addOrSubtract(1, field.multiply(errorLocations[j], xiInverse)));
+ // Above should work but fails on some Apple and Linux JDKs due to a Hotspot bug.
+ // Below is a funny-looking workaround from Steven Parkes
+ let term = self.field.multiply(errorLocations[j], xiInverse.unwrap());
+ let termPlus1 = if (term & 0x1) == 0 {
+ term | 1
+ } else {
+ term & !1
+ };
+ denominator = self.field.multiply(denominator, termPlus1);
+ }
+ }
+ result[i] = self.field.multiply(
+ errorEvaluator.evaluateAt(xiInverse.unwrap()),
+ self.field.inverse(denominator).unwrap(),
+ );
+ if (self.field.getGeneratorBase() != 0) {
+ result[i] = self.field.multiply(result[i], xiInverse.unwrap());
+ }
+ }
+ return result;
+ }
}
-
/*
* Copyright 2008 ZXing authors
*
@@ -790,58 +859,70 @@ Err(err) => return Err(ReedSolomonException::new("ArithmetricException")),
* @author William Rucklidge
*/
pub struct ReedSolomonEncoder {
-
- field : Box,
+ field: Box,
cachedGenerators: Vec,
-
}
-impl ReedSolomonEncoder{
- pub fn new( field: Box) -> Self{
- Self {
- field: field,
- cachedGenerators: vec![GenericGFPoly::new(field, &vec![1]).unwrap()],
+impl ReedSolomonEncoder {
+ pub fn new(field: Box) -> Self {
+ Self {
+ field: field,
+ cachedGenerators: vec![GenericGFPoly::new(field, &vec![1]).unwrap()],
+ }
}
- }
- fn buildGenerator( &self,degree:usize) -> GenericGFPoly{
- if degree >= self.cachedGenerators.len() {
- let mut lastGenerator = self.cachedGenerators.get(self.cachedGenerators.len() - 1).unwrap();
- for d in self.cachedGenerators.len()..=degree {
- //for (int d = cachedGenerators.size(); d <= degree; d++) {
- let nextGenerator = *lastGenerator.multiply(
- &GenericGFPoly::new(self.field, &vec![ 1, self.field.exp(d - 1 + self.field.getGeneratorBase()) ]).unwrap()).unwrap();
- self.cachedGenerators.push(nextGenerator);
- lastGenerator = &nextGenerator;
- }
+ fn buildGenerator(&self, degree: usize) -> GenericGFPoly {
+ if degree >= self.cachedGenerators.len() {
+ let mut lastGenerator = self
+ .cachedGenerators
+ .get(self.cachedGenerators.len() - 1)
+ .unwrap();
+ for d in self.cachedGenerators.len()..=degree {
+ //for (int d = cachedGenerators.size(); d <= degree; d++) {
+ let nextGenerator = *lastGenerator
+ .multiply(
+ &GenericGFPoly::new(
+ self.field,
+ &vec![1, self.field.exp(d - 1 + self.field.getGeneratorBase())],
+ )
+ .unwrap(),
+ )
+ .unwrap();
+ self.cachedGenerators.push(nextGenerator);
+ lastGenerator = &nextGenerator;
+ }
+ }
+ return *self.cachedGenerators.get(degree).unwrap();
}
- return *self.cachedGenerators.get(degree).unwrap();
- }
- pub fn encode(&self,toEncode:&mut Vec, ecBytes:usize) -> Result<(),IllegalArgumentException>{
- if (ecBytes == 0) {
- return Err(IllegalArgumentException::new("No error correction bytes"));
+ pub fn encode(
+ &self,
+ toEncode: &mut Vec,
+ ecBytes: usize,
+ ) -> Result<(), IllegalArgumentException> {
+ if (ecBytes == 0) {
+ return Err(IllegalArgumentException::new("No error correction bytes"));
+ }
+ let dataBytes = toEncode.len() - ecBytes;
+ if (dataBytes <= 0) {
+ return Err(IllegalArgumentException::new("No data bytes provided"));
+ }
+ let generator = self.buildGenerator(ecBytes);
+ let infoCoefficients = Vec::with_capacity(dataBytes);
+ infoCoefficients[0..dataBytes].clone_from_slice(&toEncode[0..dataBytes]);
+ //System.arraycopy(toEncode, 0, infoCoefficients, 0, dataBytes);
+ let info = GenericGFPoly::new(self.field, &infoCoefficients)?;
+ info = *info.multiplyByMonomial(ecBytes.try_into().unwrap(), 1)?;
+ let remainder = info.divide(&generator)?[1];
+ let coefficients = remainder.getCoefficients();
+ let numZeroCoefficients = ecBytes - coefficients.len();
+ for i in 0..numZeroCoefficients {
+ //for (int i = 0; i < numZeroCoefficients; i++) {
+ toEncode[dataBytes + i] = 0;
+ }
+ toEncode[dataBytes + numZeroCoefficients..coefficients.len()]
+ .clone_from_slice(&coefficients[0..coefficients.len()]);
+ //System.arraycopy(coefficients, 0, toEncode, dataBytes + numZeroCoefficients, coefficients.length);
+ Ok(())
}
- let dataBytes = toEncode.len() - ecBytes;
- if (dataBytes <= 0) {
- return Err( IllegalArgumentException::new("No data bytes provided"));
- }
- let generator = self.buildGenerator(ecBytes);
- let infoCoefficients = Vec::with_capacity(dataBytes);
- infoCoefficients[0..dataBytes].clone_from_slice(&toEncode[0..dataBytes]);
- //System.arraycopy(toEncode, 0, infoCoefficients, 0, dataBytes);
- let info = GenericGFPoly::new(self.field, &infoCoefficients)?;
- info = *info.multiplyByMonomial(ecBytes.try_into().unwrap(), 1)?;
- let remainder = info.divide(&generator)?[1];
- let coefficients = remainder.getCoefficients();
- let numZeroCoefficients = ecBytes - coefficients.len();
- for i in 0..numZeroCoefficients {
- //for (int i = 0; i < numZeroCoefficients; i++) {
- toEncode[dataBytes + i] = 0;
- }
- toEncode[dataBytes + numZeroCoefficients..coefficients.len()].clone_from_slice(&coefficients[0..coefficients.len()]);
- //System.arraycopy(coefficients, 0, toEncode, dataBytes + numZeroCoefficients, coefficients.length);
- Ok(())
- }
-
}