public static XPolynom operator +(XPolynom left, XPolynom right) { XPolynom @short, @long; if (left.PolynomsCount > right.PolynomsCount) { @long = left; @short = right; } else { @short = left; @long = right; } var ret = new XPolynom(@long.PolynomsCount); int i = 0; for (; i < @short.PolynomsCount; i++) { ret[i] = @long[i] + @short[i]; } for (; i < @long.PolynomsCount; i++) { ret[i] = @long[i]; } ret.ReLength(); return(ret); }
/// <summary> /// 快速RS编码 /// </summary> /// <param name="msg"></param> /// <param name="msgIndex"></param> /// <param name="msgLength"></param> /// <param name="eccCount"></param> /// <returns></returns> public static byte[] RSEncode(byte[] msg, int msgIndex, int msgLength, int eccCount) { var gp = Cache <int, XPolynom> .Get(eccCount, n => { var g = new XPolynom(FromExponent(0), FromExponent(0)); for (int i = 1; i < n; i++) { g *= new XPolynom(FromExponent(i), FromExponent(0)); } return(g); }); byte[] rem = new byte[eccCount]; Array.Copy(msg, msgIndex, rem, 0, Math.Min(msgLength, eccCount)); for (int i = 0; i < msgLength; i++) { var div = FromPolynom(rem[0]); for (int j = 1; j < eccCount; j++) { rem[j - 1] = (byte)(FromPolynom(rem[j]) + gp[eccCount - j] * div).Polynom; } if (i + eccCount < msgLength) { rem[eccCount - 1] = (byte)(FromPolynom(msg[msgIndex + i + eccCount]) + gp[0] * div).Polynom; } else { rem[eccCount - 1] = (byte)(gp[0] * div).Polynom; } } return(rem); }
public XPolynom Clone() { var ret = new XPolynom(PolynomsCount); Array.Copy(polynoms, ret.polynoms, PolynomsCount); return(ret); }
public static XPolynom FromXPow(int xExponent) { var ret = new XPolynom(xExponent + 1); ret[xExponent] = FromExponent(0); return(ret); }
public static XPolynom operator *(XPolynom left, GF right) { var ret = new XPolynom(left.PolynomsCount); for (int i = 0; i < left.PolynomsCount; i++) { ret[i] = left[i] * right; } ret.ReLength(); return(ret); }
public XPolynom MulXPow(int xExponent) { if (xExponent == 0) { return(this); } var ret = new XPolynom(PolynomsCount + xExponent); polynoms.CopyTo(ret.polynoms, xExponent); return(ret); }
public static XPolynom operator *(XPolynom left, XPolynom right) { var ret = new XPolynom(left.PolynomsCount + right.PolynomsCount - 1); for (int i = 0; i < left.PolynomsCount; i++) { for (int j = 0; j < right.PolynomsCount; j++) { ret[i + j] += left[i] * right[j]; } } return(ret); }
public XPolynom DivMod(XPolynom right, out XPolynom rem) { var divVal = new XPolynom(0); var remVal = this; var rightHead = right[right.PolynomsCount - 1]; while (true) { var xExponent = remVal.PolynomsCount - right.PolynomsCount; if (xExponent < 0) { break; } var alphaDiv = remVal[remVal.PolynomsCount - 1] / rightHead; divVal += new XPolynom(alphaDiv).MulXPow(xExponent); remVal += right.MulXPow(xExponent) * alphaDiv; } rem = remVal; return(divVal); }
public static void RSEncode(ReadOnlySpan <byte> msg, Span <byte> ecc) { int eccCount = ecc.Length; var gp = Cache <int, XPolynom> .Get(eccCount, n => { var g = new XPolynom(One, One); for (int i = 1; i < n; i++) { g *= new XPolynom(FromExponent(i), One); } return(g); }); if (msg.Length > ecc.Length) { msg.Slice(0, ecc.Length).CopyTo(ecc); } else { msg.CopyTo(ecc); ecc.Slice(msg.Length).Fill(0); } for (int i = 0; i < msg.Length; i++) { var div = FromPolynom(ecc[0]); for (int j = 1; j < eccCount; j++) { ecc[j - 1] = (FromPolynom(ecc[j]) + gp[eccCount - j] * div).Polynom; } if (i + eccCount < msg.Length) { ecc[eccCount - 1] = (FromPolynom(msg[i + eccCount]) + gp[0] * div).Polynom; } else { ecc[eccCount - 1] = (gp[0] * div).Polynom; } } }