private static byte[] CodingByte(byte[] Bytes, int Version, CorrectionLevel Level) { #region Кодирование (Data) BitSequence Data = new BitSequence(Bytes); #endregion #region Добавление служебных полей (DataTmp) int MaxLength = MaxCapacity[(int)Level, Version - 1]; BitSequence TypeCode = new BitSequence(new bool[] { false, true, false, false }); byte[] BytesCount = (Version < 10 ? new byte[] { (byte)(Bytes.Length & 0x00FF) } : new byte[] { (byte)((Bytes.Length & 0xFF00) >> 8), (byte)(Bytes.Length & 0x00FF) }); BitSequence DataLength = new BitSequence(BytesCount); BitSequence ResultBits = TypeCode + DataLength + Data; if (ResultBits.Length > MaxLength) { throw new Exception(ErrorLongData); } byte[] DataTmp = ResultBits.ToByteArray(); #endregion #region Дополнение (Result) byte[] Result = new byte[MaxLength / 8]; DataTmp.CopyTo(Result, 0); bool f = true; for (int i = DataTmp.Length; i < Result.Length; i++) { Result[i] = (f ? (byte)0b11101100 : (byte)0b00010001); f = !f; } #endregion return(Result); }
/// <summary> /// Сложение последовательностей /// </summary> /// <param name="a">Левый операнд</param> /// <param name="b">Правый операнд</param> /// <returns>Результат сложения</returns> public static BitSequence operator +(BitSequence a, BitSequence b) { BitSequence Result = new BitSequence(a.Length + b.Length); for (int i = 0; i < a.Length; i++) { Result.Bits[i] = a[i]; } for (int i = 0; i < b.Length; i++) { Result.Bits[a.Length + i] = b[i]; } return(Result); }
/// <summary> /// Получение массива байт (при необходимости дополняется нулевыми битами) /// </summary> /// <param name="IsBigEndian">Признак "прямого" следования бит в байте (старший бит впереди)</param> /// <returns>Массив байт</returns> public byte[] ToByteArray(bool IsBigEndian) { int n = (Length & 0b00000111); BitSequence tmp = (n == 0 ? this : this + new BitSequence(8 - n)); byte[] Result = new byte[tmp.Length / 8]; for (int i = 0; i < Result.Length; i++) { byte b = 0b00000000; if (IsBigEndian) { if (tmp[8 * i + 0]) { b |= 0b10000000; } if (tmp[8 * i + 1]) { b |= 0b01000000; } if (tmp[8 * i + 2]) { b |= 0b00100000; } if (tmp[8 * i + 3]) { b |= 0b00010000; } if (tmp[8 * i + 4]) { b |= 0b00001000; } if (tmp[8 * i + 5]) { b |= 0b00000100; } if (tmp[8 * i + 6]) { b |= 0b00000010; } if (tmp[8 * i + 7]) { b |= 0b00000001; } } else { if (tmp[8 * i + 0]) { b |= 0b00000001; } if (tmp[8 * i + 1]) { b |= 0b00000010; } if (tmp[8 * i + 2]) { b |= 0b00000100; } if (tmp[8 * i + 3]) { b |= 0b00001000; } if (tmp[8 * i + 4]) { b |= 0b00010000; } if (tmp[8 * i + 5]) { b |= 0b00100000; } if (tmp[8 * i + 6]) { b |= 0b01000000; } if (tmp[8 * i + 7]) { b |= 0b10000000; } } Result[i] = b; } return(Result); }
private static bool[,] CreateMatrix(byte[] Data, int Version, CorrectionLevel Level, int MaskCode) { #region Создание матрицы (bool?[,] Mtx) int BarSize = 17 + 4 * Version; bool?[,] Mtx = new bool?[BarSize, BarSize]; for (int i = 0; i < BarSize; i++) { for (int j = 0; j < BarSize; j++) { Mtx[i, j] = null; } } #endregion #region Поисковые узоры void ProcBox(int x, int y, int l, bool f) { for (int i = 0; i < l; i++) { for (int j = 0; j < l; j++) { Mtx[x + i, y + j] = f; } } } #region Большие квадраты void BigBox(int x, int y) { ProcBox(x, y, 7, true); ProcBox(x + 1, y + 1, 5, false); ProcBox(x + 2, y + 2, 3, true); } ProcBox(0, 0, 8, false); BigBox(0, 0); ProcBox(0, BarSize - 8, 8, false); BigBox(0, BarSize - 7); ProcBox(BarSize - 8, 0, 8, false); BigBox(BarSize - 7, 0); #endregion #region Малые квадраты void SmallBox(int x, int y) { ProcBox(x, y, 5, true); ProcBox(x + 1, y + 1, 3, false); ProcBox(x + 2, y + 2, 1, true); } for (int i = 0; i < AlignPosition[Version - 1].Length; i++) { for (int j = 0; j < AlignPosition[Version - 1].Length; j++) { int x = AlignPosition[Version - 1][i]; int y = AlignPosition[Version - 1][j]; if (Mtx[x, y] == null) { SmallBox(x - 2, y - 2); } } } #endregion #region Полоса bool LineFlag = true; for (int i = 6; i < BarSize; i++) { if (Mtx[6, i] == null) { Mtx[6, i] = LineFlag; } if (Mtx[i, 6] == null) { Mtx[i, 6] = LineFlag; } LineFlag = (!LineFlag); } #endregion #endregion #region Код версии if (Version > 6) { for (int i = 0; i < 3; i++) { for (int j = 0; j < 6; j++) { Mtx[j, BarSize - 11 + i] = VersionPattern[Version][i][j]; Mtx[BarSize - 11 + i, j] = VersionPattern[Version][i][j]; } } } #endregion #region Код маски и уровня BitSequence MaskPatt = MaskLevelPattern[MaskCode, (int)Level]; Mtx[0, 8] = MaskPatt[0]; Mtx[1, 8] = MaskPatt[1]; Mtx[2, 8] = MaskPatt[2]; Mtx[3, 8] = MaskPatt[3]; Mtx[4, 8] = MaskPatt[4]; Mtx[5, 8] = MaskPatt[5]; Mtx[7, 8] = MaskPatt[6]; Mtx[8, 8] = MaskPatt[7]; Mtx[8, 7] = MaskPatt[8]; Mtx[8, 5] = MaskPatt[9]; Mtx[8, 4] = MaskPatt[10]; Mtx[8, 3] = MaskPatt[11]; Mtx[8, 2] = MaskPatt[12]; Mtx[8, 1] = MaskPatt[13]; Mtx[8, 0] = MaskPatt[14]; Mtx[8, BarSize - 1] = MaskPatt[0]; Mtx[8, BarSize - 2] = MaskPatt[1]; Mtx[8, BarSize - 3] = MaskPatt[2]; Mtx[8, BarSize - 4] = MaskPatt[3]; Mtx[8, BarSize - 5] = MaskPatt[4]; Mtx[8, BarSize - 6] = MaskPatt[5]; Mtx[8, BarSize - 7] = MaskPatt[6]; Mtx[8, BarSize - 8] = true; Mtx[BarSize - 8, 8] = MaskPatt[7]; Mtx[BarSize - 7, 8] = MaskPatt[8]; Mtx[BarSize - 6, 8] = MaskPatt[9]; Mtx[BarSize - 5, 8] = MaskPatt[10]; Mtx[BarSize - 4, 8] = MaskPatt[11]; Mtx[BarSize - 3, 8] = MaskPatt[12]; Mtx[BarSize - 2, 8] = MaskPatt[13]; Mtx[BarSize - 1, 8] = MaskPatt[14]; #endregion #region Запись данных BitSequence stm = new BitSequence(Data); int xx = BarSize - 1; int yy = BarSize - 1; bool dx = false; int dy = -1; for (int n = 0; n < stm.Length; n++) { #region Выбор следующей ячейки while (Mtx[xx, yy] != null) { if (xx == 6) { xx--; continue; } if (!dx) { xx--; dx = (!dx); continue; } if ((yy + dy >= 0) && (yy + dy <= BarSize - 1)) { xx++; yy += dy; dx = (!dx); continue; } xx--; dx = (!dx); dy = -dy; } #endregion Mtx[xx, yy] = (stm[n] ^ MaskFunction[MaskCode](xx, yy)); } #endregion #region Дозаполнение пустого места for (int i = 0; i < BarSize; i++) { for (int j = 0; j < BarSize; j++) { if (Mtx[i, j] == null) { Mtx[i, j] = MaskFunction[MaskCode](i + 1, j + 1); } } } #endregion #region Формирование результата bool[,] Result = new bool[BarSize, BarSize]; for (int i = 0; i < BarSize; i++) { for (int j = 0; j < BarSize; j++) { Result[i, j] = (bool)Mtx[i, j]; } } #endregion return(Result); }