/// <summary> /// Определяет, удовлетворяет ли заданная функция критерию распространения заданной степени. /// </summary> /// <param name="Source">Исходная функция.</param> /// <param name="l">Степень критерия.</param> /// <returns></returns> public static bool HasSAC(BinaryFunction Source, int l) { if (l > Source.CountOfVariables) { throw new InvalidOperationException("Число l не должно превышать числа аргументов функции."); } if (l <= 1) { throw new InvalidOperationException("Число l должно быть больше единицы."); } for (int i = 0; i < Source.ValuesArray.Length; i++) { bool[] CurrentSet = Misc.Misc.GetBinaryArray(i, Source.CountOfVariables); int Weight = CurrentSet.Count(val => val); if (Weight >= l || Weight == 0) { continue; } if (!Source.GetDerivativeInDirection(CurrentSet).IsEquilibrium) { return(false); } } return(true); }
/// <summary> /// Возвращает расстояние между двумя функциями или, другими словами, число различающихся значений их /// векторов-столбцов. /// </summary> /// <param name="First"></param> /// <param name="Second"></param> /// <returns></returns> public static int Distance(BinaryFunction First, BinaryFunction Second) { if (First.ValuesArray.Length != Second.ValuesArray.Length) { throw new InvalidOperationException("Длины столбцов-значений функций должны совпадать."); } return(First.ValuesArray.Select((val, ind) => val ^ Second.ValuesArray[ind]).Count(val => val)); }
/// <summary> /// Возвращает максимальный порядок устойчивости заданной функции. /// </summary> /// <param name="Source"></param> /// <returns></returns> public static int GetMaxStableValue(BinaryFunction Source) { int FixedVariablesCount = 1; for (; FixedVariablesCount <= Source.CountOfVariables; FixedVariablesCount++) { //Выбираем, какие переменные фиксировать. Задаем наборы, в которых на местах фиксированных переменных будут 1, на месте свободных 0. List <bool[]> States = new List <bool[]>(); for (int i = 0; i < (int)Math.Pow(2, Source.CountOfVariables); i++) { bool[] CurrentSet = Misc.Misc.GetBinaryArray(i, Source.CountOfVariables); if (CurrentSet.Count(val => val) != FixedVariablesCount) { continue; } if (States.Any(set => set.Select((boo, ind) => boo == CurrentSet[ind]).All(boo => boo))) { continue; } States.Add(CurrentSet); //Выбрали, какие переменные зафиксировать. //Создаем словарь, где ключи - конкретный зафиксированный набор, а значения - значения столбца функции в таких наборах Dictionary <bool[], List <bool> > NewFunctions = new Dictionary <bool[], List <bool> >(); for (int j = 0; j < Source.ValuesArray.Length; j++) { //Текущая строка таблицы истинности bool[] CurrentFuncSet = Misc.Misc.GetBinaryArray(j, Source.CountOfVariables); bool FuncValue = Source.ValuesArray[j]; if (NewFunctions.Keys.Any(row => row.Select((variable, index) => !CurrentSet[index] || variable == CurrentFuncSet[index]) .All(res => res))) { NewFunctions[NewFunctions.Keys.First(row => row.Select((variable, index) => !CurrentSet[index] || variable == CurrentFuncSet[index]) .All(res => res))].Add(FuncValue); } else { NewFunctions.Add(CurrentFuncSet, new List <bool>(new[] { FuncValue })); } } if (NewFunctions.Values.Any(val => !new BinaryFunction(val.ToArray()).IsEquilibrium)) { return(FixedVariablesCount - 1); } } } return(FixedVariablesCount - 1); }
/// <summary> /// Возвращает строковое представления формулы преобразования Фурье для заданной функции. /// </summary> /// <param name="Source"></param> /// <returns></returns> public static string GetFourierTransformString(BinaryFunction Source) { bool[][] FourierTransformFormula = GetFourierTransformFormula(Source); StringBuilder Result = new StringBuilder(FourierTransformFormula[0].All(boo => !boo) ? "1" : $"(-1)^{string.Join("⊕", FourierTransformFormula[0].Select((val, ind) => $"u{ind + 1}").Where((val, ind) => FourierTransformFormula[0][ind]))}"); for (int i = 1; i < FourierTransformFormula.Length; i++) { Result.Append( $" + (-1)^{string.Join("⊕", FourierTransformFormula[i].Select((val, ind) => $"u{ind + 1}").Where((val, ind) => FourierTransformFormula[i][ind]))}"); } return(Result.ToString()); }
/// <summary> /// Возвращает массив-формулу преобразования Фурье для заданной булевой функции /// </summary> /// <param name="Source"></param> /// <returns></returns> private static bool[][] GetFourierTransformFormula(BinaryFunction Source) { List <bool[]> FourierTransformFormula = new List <bool[]>(); for (int i = 0; i < Source.ValuesArray.Length; i++) { if (!Source.ValuesArray[i]) { continue; } FourierTransformFormula.Add(Misc.Misc.GetBinaryArray(i, Source.CountOfVariables)); } return(FourierTransformFormula.ToArray()); }
/// <summary> /// Определяет наивысшую степень критерия распространения для заданной функции. /// </summary> /// <param name="Source">Исходная функция.</param> /// <returns></returns> public static int GetMaxSACValue(BinaryFunction Source) { for (int l = 2; l < Source.CountOfVariables; l++) { for (int i = 0; i < Source.ValuesArray.Length; i++) { bool[] CurrentSet = Misc.Misc.GetBinaryArray(i, Source.CountOfVariables); int Weight = CurrentSet.Count(val => val); if (Weight != l) { continue; } if (!Source.GetDerivativeInDirection(CurrentSet).IsEquilibrium) { return(l - 1); } } } return(Source.CountOfVariables); }
/// <summary> /// Возвращает максимальный порядок корреляционной имунности для заданной функции. /// </summary> /// <param name="Source"></param> /// <returns></returns> public static int GetMaxCorrelationImmunityValue(BinaryFunction Source) { for (int m = 1; m <= Source.CountOfVariables; m++) { for (int i = 0; i < Source.ValuesArray.Length; i++) { bool[] CurrentSet = Misc.Misc.GetBinaryArray(i, Source.CountOfVariables); int Weight = CurrentSet.Count(val => val); if (Weight != m) { continue; } if (Source.WalshHadamardSpectrum[i] != 0) { return(m - 1); } } } return(Source.CountOfVariables); }
/// <summary> /// Возвращает спектр Фурье для заданной булевой функции. /// </summary> /// <param name="Source"></param> /// <returns></returns> public static int[] GetFourierSpectrum(BinaryFunction Source) { bool[][] FourierTransformFormula = GetFourierTransformFormula(Source); int[] Result = new int[Source.ValuesArray.Length]; for (int i = 0; i < Source.ValuesArray.Length; i++) { bool[] CurrentSet = Misc.Misc.GetBinaryArray(i, Source.CountOfVariables); Result[i] = FourierTransformFormula[0].All(boo => !boo) ? 1 : 0; for (int j = FourierTransformFormula[0].All(boo => !boo) ? 1 : 0; j < FourierTransformFormula.Length; j++) { Result[i] += (int)Math.Pow(-1, CurrentSet.Where((val, ind) => FourierTransformFormula[j][ind]) .Aggregate(false, (Current, next) => Current ^ next) ? 1 : 0); } } return(Result); }
/// <summary> /// Определеяет, имеет ли функция корреляционную иммунность порядка m. /// </summary> /// <param name="Source"></param> /// <param name="m"></param> /// <returns></returns> public static bool IsCorrelationImmune(BinaryFunction Source, int m) { if (m >= Source.CountOfVariables) { throw new InvalidOperationException("Число m должно быть меньше числа аргументов функции."); } for (int i = 0; i < Source.ValuesArray.Length; i++) { bool[] CurrentSet = Misc.Misc.GetBinaryArray(i, Source.CountOfVariables); int Weight = CurrentSet.Count(val => val); if (Weight > m || Weight == 0) { continue; } if (Source.WalshHadamardSpectrum[i] != 0) { return(false); } } return(true); }
/// <summary> /// Определяет, удовлетворяет ли заданная функция критерию распространения заданной степени и порядка. /// </summary> /// <param name="Source">Исходная функция.</param> /// <param name="l">Степень критерия распространения.</param> /// <param name="k">Порядок критерия распространения.</param> /// <returns></returns> public static bool HasSAC(BinaryFunction Source, int l, int k) { if (l > Source.CountOfVariables) { throw new InvalidOperationException("Число l не должно превышать числа аргументов функции."); } if (l <= 1) { throw new InvalidOperationException("Число l должно быть больше единицы."); } if (k >= Source.CountOfVariables) { throw new InvalidOperationException("Число k должно быть меньше числа аргументов функции."); } if (k < 1) { throw new InvalidOperationException("Число k не должно быть меньше единицы."); } //Выбираем, какие переменные фиксировать. Задаем наборы, в которых на местах фиксированных переменных будут 1, на месте свободных 0. List <bool[]> States = new List <bool[]>(); for (int i = 0; i < (int)Math.Pow(2, Source.CountOfVariables); i++) { bool[] CurrentSet = Misc.Misc.GetBinaryArray(i, Source.CountOfVariables); if (CurrentSet.Count(val => val) != k) { continue; } if (States.Any(set => set.Select((boo, ind) => boo == CurrentSet[ind]).All(boo => boo))) { continue; } States.Add(CurrentSet); //Выбрали, какие переменные зафиксировать. //Создаем словарь, где ключи - конкретный зафиксированный набор, а значения - значения столбца функции в таких наборах Dictionary <bool[], List <bool> > NewFunctions = new Dictionary <bool[], List <bool> >(); for (int j = 0; j < Source.ValuesArray.Length; j++) { //Текущая строка таблицы истинности bool[] CurrentFuncSet = Misc.Misc.GetBinaryArray(j, Source.CountOfVariables); bool FuncValue = Source.ValuesArray[j]; if (NewFunctions.Keys.Any(row => row.Select((variable, index) => !CurrentSet[index] || variable == CurrentFuncSet[index]) .All(res => res))) { NewFunctions[NewFunctions.Keys.First(row => row.Select((variable, index) => !CurrentSet[index] || variable == CurrentFuncSet[index]) .All(res => res))].Add(FuncValue); } else { NewFunctions.Add(CurrentFuncSet, new List <bool>(new[] { FuncValue })); } } if (NewFunctions.Values.Any(val => !new BinaryFunction(val.ToArray()).HasSAC(l))) { return(false); } } return(true); }