/** * RSコードのエンコード * * @param data int[] * 入力データ配列 * @param length int * 入力データ長 * @param parity int[] * パリティ格納用配列 * @param parityStartPos int * パリティ格納用Index * @return bool */ public void encode(byte[] data, int datapos, int length, byte[] parity, int parityStartPos) { if (length < 0 || length + npar > galois.Max) { throw new Exception("RsEncode: wrong length"); } /* * パリティ格納用配列 * wr[0] 最上位 * wr[npar - 1] 最下位 なのに注意 * これでパリティを逆順に並べかえなくてよいので、arraycopyが使える */ byte[] wr = new byte[npar]; for (int idx = datapos; idx < datapos + length; idx++) { int ib = wr[0] ^ data[idx]; for (int i = 0; i < npar - 1; i++) { wr[i] = (byte)(wr[i + 1] ^ galois.mul(ib, encodeGx[i])); } wr[npar - 1] = (byte)galois.mul(ib, encodeGx[npar - 1]); } if (parity != null) { Array.Copy(wr, 0, parity, parityStartPos, npar); } }
/** * RSコードのエンコード * * @param data int[] * 入力データ配列 * @param length int * 入力データ長 * @param parity int[] * パリティ格納用配列 * @param parityStartPos int * パリティ格納用Index * @return bool */ public unsafe void encode(ushort *data, int length, ushort *parity) { if (length < 0 || length + npar > galois.Max) { throw new Exception("RsEncode: wrong length"); } /* * パリティ格納用配列 * wr[0] 最上位 * wr[npar - 1] 最下位 なのに注意 * これでパリティを逆順に並べかえなくてよいので、arraycopyが使える */ ushort *wr = stackalloc ushort[npar]; for (int idx = 0; idx < length; idx++) { int ib = wr[0] ^ data[idx]; for (int i = 0; i < npar - 1; i++) { wr[i] = (ushort)(wr[i + 1] ^ galois.mul(ib, encodeGx[i])); } wr[npar - 1] = (ushort)galois.mul(ib, encodeGx[npar - 1]); } for (int i = 0; i < npar; i++) { parity[i] = wr[i]; } }
/// <summary> /// Modified Berlekamp-Massey /// </summary> /// <param name="sigma"> /// σ(z)格納用配列、最大npar/2 + 2個の領域が必要 /// σ0,σ1,σ2, ... σ[jisu] /// </param> /// <param name="omega"> /// ω(z)格納用配列、最大npar/2 + 1個の領域が必要 /// ω0,ω1,ω2, ... ω[jisu-1] /// </param> /// <param name="syn"> /// シンドローム配列 /// s0,s1,s2, ... s[npar-1] /// </param> /// <returns> /// >= 0: σの次数 /// else: エラー /// </returns> public unsafe int calcSigmaMBM(int *sigma, int *syn) { int *sg0 = stackalloc int[npar + 1]; int *sg1 = stackalloc int[npar + 1]; int *wk = stackalloc int[npar + 1]; sg0[1] = 1; sg1[0] = 1; int jisu0 = 1; int jisu1 = 0; int m = -1; for (int n = 0; n < npar; n++) { // 判別式を計算 int d = syn[n]; for (int i = 1; i <= jisu1; i++) { d ^= galois.mul(sg1[i], syn[n - i]); } if (d != 0) { int logd = galois.toLog(d); for (int i = 0; i <= n; i++) { wk[i] = sg1[i] ^ galois.mulExp(sg0[i], logd); } int js = n - m; if (js > jisu1) { for (int i = 0; i <= jisu0; i++) { sg0[i] = galois.divExp(sg1[i], logd); } m = n - jisu1; jisu1 = js; jisu0 = js; } for (int i = 0; i < npar; i++) { sg1[i] = wk[i]; } } for (int i = jisu0; i > 0; i--) { sg0[i] = sg0[i - 1]; } sg0[0] = 0; jisu0++; } if (sg1[jisu1] == 0) { return(-1); } //galois.mulPoly(omega, sg1, syn, npar / 2 + 1, npar, npar); for (int i = 0; i < Math.Min(npar / 2 + 2, npar); i++) { sigma[i] = sg1[i]; } return(jisu1); }