Exemplo n.º 1
0
        //статическая функция для замены НЗБ (внедрения текста в изображение путем замены битов)
        public static StegoBitmap Hide(StegoBitmap bitmap, string text, Colours colour)
        {
            byte[] sourceColour = bitmap.GetColour(colour);                                         // массив байтов указанного цвета для данного StegoBitmap
            byte[] stgText      = Encoding.GetEncoding(1251).GetBytes(text);                        // массив байтов введеных символов
            byte[] len          = CommonFunc.LenInBytes(text.Length, CommonFunc.Size(text.Length)); // массив байтов из длины текста в соответвии с размером его длины
            byte[] stgBytes     = new byte[2 + len.Length + stgText.Length];                        //массив для скрытого текста размером в длину текста + размер длины + два дополнительных байта
            stgBytes[0] = Convert.ToByte('L');                                                      // первый элемент массива содержит пометку, что в изображении скрыт текст
            stgBytes[1] = CommonFunc.Size(text.Length);                                             // второй элемент массива размер длины
            int ind = 0;

            for (int i = 0; i < len.Length; i++)
            {
                stgBytes[i + 2] = len[ind++]; // сохраняем в массив байты из длины текста в соответвии с размером его длины
            }
            ind = 0;
            for (int i = 0; i < stgText.Length; i++)
            {
                stgBytes[i + 2 + len.Length] = stgText[ind++]; // сохраняем в массив скрываемый текст
            }
            // булевский массив из массива байтов
            bool[] stgBoolBits = stgBytes.SelectMany(e => CommonFunc.ByteBoolArr(e)).ToArray(); // SelectMany используется для создания выходной последовательности с проекцией "один ко многим" из входной последовательности. Select вернет один выходной элемент для каждого входного элемента, SelectMany - ноль или более выходных элементов для каждого входного
            // проходим по элементам булевского массива текста. если бит текста true и байт цвета четен, то увеличиваем его на 1, в обратной ситуации - уменьшаем на 1, в остальный случаях байт цвета остается не изменным  (0 и 0 => 0, 1 и 1 => 1, 0 и 1 => 1, 1 и 0 => 0)
            for (int i = 0; i < stgBoolBits.Length; i++)
            {
                if ((sourceColour[i] % 2 == 0) && stgBoolBits[i])
                {
                    sourceColour[i]++;
                }
                else if ((sourceColour[i] % 2 == 1) && !stgBoolBits[i])
                {
                    sourceColour[i]--;
                }
            }
            return(new StegoBitmap(bitmap, sourceColour, colour));
        }
Exemplo n.º 2
0
        // внедрение текста
        private static void SetText(byte[] txt, ref List <double[, ]> DCT, int coefDif)
        {
            List <int> freePos = new List <int>(); // свободные позиции в соответствии с размером списка коэффициентов ДКП

            for (int i = 0; i < DCT.Count; i++)
            {
                freePos.Add(i);
            }
            for (int i = 0; i < txt.Length; i++)
            {
                bool[] bitsSymb = CommonFunc.ByteBoolArr(txt[i]); //перевод байтого символа текста в булевый массив
                for (int j = 0; j < 8; j++)
                {
                    bool currentBit = bitsSymb[j];
                    int  pos        = freePos[0]; // позиция
                    freePos.RemoveAt(0);
                    // берем значения коэффициентов ДКП по модулю
                    double AbsP1 = Math.Abs(DCT[pos][p1.X, p1.Y]);
                    double AbsP2 = Math.Abs(DCT[pos][p2.X, p2.Y]);
                    int    z1 = 1, z2 = 1; // переменные для сохранения знака первичных значений коэффициентов ДКП по модулю
                    if (DCT[pos][p1.X, p1.Y] < 0)
                    {
                        z1 = -1;
                    }
                    if (DCT[pos][p2.X, p2.Y] < 0)
                    {
                        z2 = -1;
                    }
                    if (currentBit) //для передачи бита "1" стремяться, чтобы разница абсолютных значений коэффициентов ДКП была меньше по сравнению с некоторой отрицательной величиной
                    {
                        if (AbsP1 - AbsP2 >= -coefDif)
                        {
                            AbsP2 = coefDif + AbsP1 + 1;
                        }
                    }
                    else //для передачи бита "0" стремятся, чтобы разница абсолютных значений коэффициентов ДКП превышала некоторую положительную величину
                    {
                        if (AbsP1 - AbsP2 <= coefDif)
                        {
                            AbsP1 = coefDif + AbsP2 + 1;
                        }
                    }
                    // присваиваем коэффициентам ДКП новые значения
                    DCT[pos][p1.X, p1.Y] = z1 * AbsP1;
                    DCT[pos][p2.X, p2.Y] = z2 * AbsP2;
                }
            }
        }
Exemplo n.º 3
0
        // внедрение текста
        private static void SetText(byte[] txt, ref List <double[, ]> blocks, int coefDif)
        {
            List <int> freePos = new List <int>(); // свободные позиции в соответствии с размером списка коэффициентов ДКП

            for (int i = 0; i < blocks.Count; i++)
            {
                freePos.Add(i);
            }
            for (int i = 0; i < txt.Length; i++)
            {
                bool[] bitsSymb = CommonFunc.ByteBoolArr(txt[i]); //перевод байтого символа текста в булевый массив
                for (int j = 0; j < 8; j++)
                {
                    bool currentBit = bitsSymb[j];
                    int  pos        = freePos[0]; // позиция
                    freePos.RemoveAt(0);

                    // берем значения коэффициентов ДКП в точках
                    double P1      = blocks[pos][p1.X, p1.Y];
                    double P2      = blocks[pos][p2.X, p2.Y];
                    double P3      = blocks[pos][p3.X, p3.Y];
                    bool   HideBit = false;
                    if (ValidMoonotony(blocks[pos]) && ValidSharpness(blocks[pos]))
                    {
                        if (currentBit) //для передачи бита "1" стремятся, чтобы третий коэффициент стал большим по сравнению с первым и вторым коэффициентами
                        {
                            if ((Math.Max(P1, P2) - P3) > 0.001 || Math.Abs(P3 - Math.Max(P1, P2)) < 0.001)
                            {
                                P3 = Math.Max(P1, P2) + coefDif / 2;
                                if (P1 > P2)
                                {
                                    P1 -= coefDif / 2;
                                }
                                else
                                {
                                    P2 -= coefDif / 2;
                                }
                            }
                        }
                        else //для передачи бита "0" стремятся, чтобы третий коэффициент стал меньше любого из первых двух
                        {
                            if ((P3 - Math.Min(P1, P2)) > 0.001 || Math.Abs(P3 - Math.Min(P1, P2)) < 0.001)
                            {
                                P3 = Math.Min(P1, P2) - coefDif / 2;
                                if (P1 < P2)
                                {
                                    P1 += coefDif / 2;
                                }
                                else
                                {
                                    P2 += coefDif / 2;
                                }
                            }
                        }
                        HideBit = true;
                    }
                    //присваиваем коэффициентам ДКП новые значения
                    blocks[pos][p1.X, p1.Y] = P1;
                    blocks[pos][p2.X, p2.Y] = P2;
                    blocks[pos][p3.X, p3.Y] = P3;
                    if (HideBit && TestValidInver(blocks[pos]))
                    {
                        j++;
                    }

                    j--;
                }
            }
        }
Exemplo n.º 4
0
        // функция превращает последний бит байта в булевую переменную
        private static bool[] LastBit(byte b, int num)
        {
            var arr = CommonFunc.ByteBoolArr(b);           // переводим массив байтов в булев

            return(arr.Skip(8 - num).Take(num).ToArray()); // берем только последний элемент массива (отвечающий за последний бит)
        }