public Container(ref PreparedData data, Point[] selectedPoints, Point[] NotSelectedPoints, int x, int y, int xSize, int ySize)
        {
            if (selectedPoints != null)
            {
                this.points_Checked = new General.Point[selectedPoints.Length];

                for (int i = 0; i < selectedPoints.Length; i++)
                {
                    this.points_Checked[i] = new General.Point(selectedPoints[i].x + x, selectedPoints[i].y + y);
                }

                this.sumBits_Checked = getSumBits(this.points_Checked, ref data);
            }

            if (NotSelectedPoints != null)
            {
                this.points_NotChecked = new General.Point[NotSelectedPoints.Length];

                for (int i = 0; i < NotSelectedPoints.Length; i++)
                {
                    this.points_NotChecked[i] = new General.Point(NotSelectedPoints[i].x + x, NotSelectedPoints[i].y + y);
                }

                this.sumBits_NotChecked = getSumBits(this.points_NotChecked, ref data);
            }

            this.xSize = xSize;
            this.ySize = ySize;
        }
        public Container(int x1, int y1, int x2, int y2, ref PreparedData data)
        {
            this.top = new Point(x1, y1); // верхняя левая точка контейнера
            this.bottom = new Point(x2, y2); // верхняя правая точка контейнера

            sumBits = getSumBits(this.top, this.bottom, ref data); // получаем "сумму по модулю" всех бит контейнера
        }
Exemple #3
0
        public void Coder(ref PreparedData data, int xSize, int ySize)
        {
            int calContainers = (data.img.Width / xSize); // получаю количество контейнеров по оси Х
            int rowContainers = (data.img.Height / ySize); // получаю количество контейнеров по оси Y
            int numberOfContainers = rowContainers * calContainers; // Получаю общее количество контейнеров

            if (numberOfContainers < data.msgBits.Length) // проверяю возможность внедрении информации относительно размеров контейнеров и длины сообщения
            {
                throw new Exception("Не достаточно места для хранения информации. Измените размер контейнера или длину сообщения");
            }

            Container[] containers = new Container[data.msgBits.Length]; // формирую массив контейнеров (по одномерному должно работать быстрее) Длинной в сообщение

            // формирую блоки и считаю их контрольные суммы
            getContainers(ref data, ref containers, xSize, ySize, calContainers, rowContainers, data.msgBits.Length);

            // начинаем заполнять блоки информацией
            int index = 0;
            while (index < containers.Length)
            {
                if (containers[index].sumBits != data.msgBits[index])
                {
                    //Console.WriteLine("Container #{0}: Changed from {1} to {2}", index, containers[index].sumBits, msgBits[index]);
                    containers[index].updateValue(data.msgBits[index], ref data);
                }
                index++;
            }

            data.imgCoded = Utils.setColorChanel(ref data);
        }
        public string Decrypt(ref PreparedData data, string start, int offset = 0)
        {
            start = Information.key;

            BitArray startBits = new BitArray(Encoding.UTF8.GetBytes(start)); // введенные пользователем
            BitArray startBitsFromImage = new BitArray(startBits.Length); // из изображения

            int m = 0; // по у
            int n = 0; // по х

            int limit = start.Length; // граница считывания

            string result = getInformation(ref data, ref m, ref n, limit, offset); // ключ
            if (!result.Equals(start)) throw new Exception("We don't have information here, or key not valid");

            limit += (32 / 8);
            string length = getInformation(ref data, ref m, ref n, limit, offset); // длина сообщения (дает с мусором)

            limit += Convert.ToInt32(length);
            string message = getInformation(ref data, ref m, ref n, limit, offset); // сообщение

            Information.msg = message;

            return message;
        }
        public void Coder(ref PreparedData data, General.Point[] selectedPoints, General.Point[] NotSelectedPoints, int xSize, int ySize)
        {
            int colContainers = (data.img.Width / xSize); // получаю количество контейнеров по оси Х
            int rowContainers = (data.img.Height / ySize); // получаю количество контейнеров по оси Y
            int numberOfContainers = rowContainers * colContainers; // Получаю общее количество контейнеров

            if (numberOfContainers < data.msgBits.Length) // проверяю возможность внедрении информации относительно размеров контейнеров и длины сообщения
            {
                throw new Exception("Не достаточно места для хранения информации. Измените размер контейнера или длину сообщения");
            }

            Methods.Block_Different_Shape.Container[] containers = new Methods.Block_Different_Shape.Container[data.msgBits.Length]; // формирую массив контейнеров (по одномерному должно работать быстрее) Длинной в сообщение

            getContainers(ref data, ref containers, selectedPoints, NotSelectedPoints, xSize, ySize, rowContainers, colContainers, containers.Length);

            // начинаем заполнять блоки информацией
            int index = 0;
            while (index < containers.Length)
            {
                if (containers[index].points_NotChecked == null || containers[index].points_Checked == null)
                {
                    if (containers[index].points_NotChecked == null)
                    {
                        if (containers[index].sumBits_Checked != data.msgBits[index])
                        {
                            containers[index].updateValue(data.msgBits[index], false, ref data);
                        }
                    }
                    else
                    {
                        if (containers[index].sumBits_NotChecked != data.msgBits[index])
                        {
                            containers[index].updateValue(data.msgBits[index], true, ref data);
                        }
                    }
                }
                else
                {
                    if(index % 2 == 0 && containers[index].sumBits_Checked != data.msgBits[index])
                    {
                        containers[index].updateValue(data.msgBits[index], Convert.ToBoolean(index % 2), ref data);
                    }

                    else if(index % 2 == 1 && containers[index].sumBits_NotChecked != data.msgBits[index])
                    {
                        containers[index].updateValue(data.msgBits[index], Convert.ToBoolean(index % 2), ref data);
                    }
                }
                index++;
            }

            data.imgCoded = Utils.setColorChanel(ref data);
        }
        public bool getSumBits(Point[] points, ref PreparedData data)
        {
            bool sum = false;

            // полходим по всему контейнеру
            for (int i = 0; i < points.Length; i++)
            {
                char[] colorBits = Convert.ToString(data.imgChanel[points[i].y][points[i].x], 2).ToCharArray(); // переводим текущую цветовую компоненту в двоичный вид
                if (colorBits[colorBits.Length - 1] == '1') // если последний бит единица
                {
                    sum ^= true;   // складываем с единицей
                }
                else
                {
                    sum ^= false; // складываем с нулем
                }
            }
            return sum;
        }
        // обновление значения "суммы по модулю"
        public void updateValue(bool value, ref PreparedData data)
        {
            // случайным образом выбираем позицию в контейнере
            Random rnd = new Random();
            int x = rnd.Next(this.top.x, this.bottom.x);
            int y = rnd.Next(this.top.y, this.bottom.y);

            char[] colorBits = Convert.ToString(data.imgChanel[y][x], 2).ToCharArray(); // переводим текущую цветовую компоненту в 2й вид
            if (colorBits[colorBits.Length - 1] == '1') // если последний бит единица
            {
                colorBits[colorBits.Length - 1] = '0';   // записываем в объект 1
            }
            else
            {
                colorBits[colorBits.Length - 1] = '1'; // записываем в объект 0
            }

            data.imgChanel[y][x] = Convert.ToInt32(new string(colorBits), 2); // записываем обновленное значение цветовой компоненты в цветовом канале

            sumBits = value; // обновляем значение в объекте контейнера
        }
        public bool getSumBits(Point top, Point bottom, ref PreparedData data)
        {
            bool sum = false;

            // полходим по всему контейнеру
            for (int y = top.y; y < bottom.y; y++)
            {
                for (int x = top.x; x < bottom.x; x++)
                {
                    char[] colorBits = Convert.ToString(data.imgChanel[y][x], 2).ToCharArray(); // переводим текущую цветовую компоненту в двоичный вид
                    if (colorBits[colorBits.Length - 1] == '1') // если последний бит единица
                    {
                        sum ^= true;   // складываем с единицей
                    }
                    else
                    {
                        sum ^= false; // складываем с нулем
                    }
                }
            }
            return sum;
        }
        public void Encrypt(ref PreparedData data, int offset = 0)
        {
            Console.WriteLine("Message length including offset {0}", data.msgBits.Length * (offset + 1));
            if (data.img.Height * data.img.Width < data.msgBits.Length * (offset + 1)) throw new Exception("Не достаточно места для сокрытия данных");

            int m = 0;
            int n = 0;

            while (m < data.img.Height)
            {
                n = n - data.imgChanel[m].Length;
                if (n % data.imgChanel[m].Length == 0) n = 0;

                while (n < data.img.Width)
                {
                    if (((m * data.img.Width + n) / (offset + 1)) >= data.msgBits.Length)
                    {
                        data.imgCoded = Utils.setColorChanel(ref data);
                        return; // нужно присмотреться
                    }

                    char[] colorBits = Convert.ToString(data.imgChanel[m][n], 2).ToCharArray();

                    if (data.msgBits[((m * data.img.Width + n) / (offset + 1))])
                    {
                        colorBits[colorBits.Length - 1] = '1';
                    }
                    else
                    {
                        colorBits[colorBits.Length - 1] = '0';
                    }

                    data.imgChanel[m][n] = Convert.ToInt32(new string(colorBits), 2);
                    n += offset + 1;
                }
                m++;
            }
        }
Exemple #10
0
        private void getContainers(ref PreparedData data, ref Container[] containers, int xSize, int ySize, int calContainers, int rowContainers, int limit, int startFrom = 0)
        {
            int index = 0; // индекс в контейнера

            int yStart = 0;
            int xStart = 0;

            if(startFrom > 0)
            {
                yStart = startFrom / calContainers;
                xStart = startFrom % calContainers;
            }

            for (int y = yStart * ySize; y < ySize * rowContainers && index < limit; y += ySize)
            {
                for (int x = xStart * xSize; x < xSize * calContainers && index < limit; x += xSize)
                {
                    containers[index] = new Container(x, y, (x + xSize) - 1, (y + ySize) - 1, ref data); // берем текущие кооридинаты и координаты, смещенные относительно
                    index++;
                }
                xStart = 0;
            }
        }
        private string getInformation(ref PreparedData data, ref int m, ref int n, int limit, int offset = 0)
        {
            int k = 0; // итератор по данным

            BitArray hiddenData = new BitArray(limit * 8);

            while(m < data.img.Height) {

                if (n - data.imgChanel[m].Length > 0) n = n - data.imgChanel[m].Length;
                if (n % data.imgChanel[m].Length == 0) n = 0;

                while(n < data.img.Width) {

                    if (((m * data.img.Width + n) / (offset + 1)) >= (limit * 8))
                    {
                        byte[] hiddenDataBytes = new byte[limit];
                        hiddenData.CopyTo(hiddenDataBytes, 0);

                        return Encoding.UTF8.GetString(hiddenDataBytes); // изменить
                    }

                    char[] bitsOfColorComponent = Convert.ToString(data.imgChanel[m][n], 2).ToCharArray(); // переводим текущу. цветовую компоненту в 2й вид
                    if (bitsOfColorComponent[bitsOfColorComponent.Length - 1] == '1') // если последний бит единица
                    {
                        hiddenData[k] = true;   // записываем в объект 1
                    }
                    else
                    {
                        hiddenData[k] = false; // записываем в объект 0
                    }
                    n += offset + 1; // сдвигаем указатель дальше
                    k++;
                }
                m++;
            }
            return null;
        }
Exemple #12
0
        public string Decoder(ref PreparedData data, int xSize, int ySize, string start)
        {
            string message = null;
            int startFrom = 0;

            BitArray startBits = new BitArray(Encoding.UTF8.GetBytes(start)); // введенные пользователем
            BitArray startBitsFromImage = new BitArray(startBits.Length); // из изображения

            int calContainers = (data.img.Width / xSize); // получаю количество контейнеров по оси Х
            int rowContainers = (data.img.Height / ySize); // получаю количество контейнеров по оси Y
            int numberOfContainers = rowContainers * calContainers; // Получаю общее количество контейнеров

            int limit = start.Length * 8; // граница считывания
            int index = 0;

            // ключ
            // формирую блоки и считаю их контрольные суммы
            message = getDecodedInfo(ref data, xSize, ySize, calContainers, rowContainers, ref startFrom, limit, ref index);
            Console.WriteLine("Ключ: {0}", message);

            if(!message.Equals(start)) throw new Exception("Информация не найдена или ключ не верен");

            limit = 32;

            message = getDecodedInfo(ref data, xSize, ySize, calContainers, rowContainers, ref startFrom, limit, ref index);
            Console.WriteLine("Длина: {0}", message);

            limit = Convert.ToInt32(message) * 8;

            message = getDecodedInfo(ref data, xSize, ySize, calContainers, rowContainers, ref startFrom, limit, ref index);
            Console.WriteLine("Сообщение: {0}", message);

            Information.msg = message;

            return message;
        }
        static void Main(string[] args)
        {
            // Отладка. Замер времени выполнения
            Stopwatch sw = new Stopwatch();

            // Входные данные
            Information.msg = "Helloooooworld----------F**K";
            Information.key = "Nachalo";
            Information.imgPath = @"C:\Users\Евгений\Pictures\check-in-minion-BMP.bmp";
            Information.colorChanel = "B";
            Information.container.xSize = 128;
            Information.container.ySize = 128;

            // Обработка входных данных
            // Явное преобразование регистра цветовой компоненты
            Information.colorChanel = Information.colorChanel.ToUpper();

            // Преобразование секретного сообщения в массив бит
            BitArray msgBit = new BitArray(Encoding.UTF8.GetBytes(Information.msg));

            // Получение изобрадения по выбранному цветовому каналу
            Bitmap img = new Bitmap(Information.imgPath, true);

            // Вывод информации о входных данных
            Console.WriteLine("Шифруемое сообщение: {0}", Information.msg);
            Console.WriteLine("Количество бит в сообщении: {0}", msgBit.Length);
            Console.WriteLine("Размер изображения: {0}х{1}", img.Width, img.Height);
            Console.WriteLine("Количество пикселей в изображении: {0}", img.Width * img.Height);
            Console.WriteLine("Размер контейнера: {0}x{1}", Information.container.xSize, Information.container.ySize);
            Console.WriteLine("Количество пикселей в контейнере: {0}", Information.container.xSize * Information.container.ySize);

            //// Замер времени выполнения
            //Console.WriteLine();
            //Console.WriteLine("Получение цветового канала...");
            //sw.Start();
            //int[][] imgChanel = Utils.getColorChanel(img, Information.colorChanel);
            //sw.Stop();
            //Console.WriteLine("Затрачено времени: {0}", sw.Elapsed);
            //sw.Reset();

            PreparedData data = new PreparedData("code");
            LeastSignificantBit lsb = new LeastSignificantBit();
            string decrypt_message;

            lsb.Encrypt(ref data, 0);
            decrypt_message = lsb.Decrypt(ref data, Information.key, 0);

            //Block blockMethod = new Block();

            //blockMethod.Coder(ref data, 10, 10);
            //blockMethod.Decoder(ref data, 10, 10, "Nachalo");

            Console.WriteLine("Message is \"{0}\"", decrypt_message);

            // Чего потеря в весе почти в 2 раза?
            // #1 Отсутствие метаданных изображения
            Console.WriteLine();
            Console.WriteLine("Запись обработанного цветового канала...");
            sw.Start();
            // Utils.setColorChanel(img, data.imgChanel, Information.colorChanel).Save(@"C:\Users\Евгений\Pictures\check-in-minion2.bmp");
            sw.Stop();
            Console.WriteLine("Затрачено времени: {0}", sw.Elapsed);

            Console.WriteLine();
            Console.WriteLine("Выполнено");

            Console.ReadLine();
        }
Exemple #14
0
        private string getDecodedInfo(ref PreparedData data, int xSize, int ySize, int calContainers, int rowContainers, ref int startFrom, int limit, ref int index)
        {
            startFrom += index;

            BitArray hiddenData = new BitArray(limit); // считанные данные;
            byte[] hiddenDataBytes = new byte[limit / 8];;
            Container[] containers = new Container[hiddenData.Length];

            // формирую блоки и считаю их контрольные суммы
            getContainers(ref data, ref containers, xSize, ySize, calContainers, rowContainers, hiddenData.Length, startFrom);

            index = 0;
            while (index < hiddenData.Length)
            {
                hiddenData[index] = containers[index].sumBits;
                index++;
            }

            hiddenData.CopyTo(hiddenDataBytes, 0);

            return Encoding.UTF8.GetString(hiddenDataBytes); // расшифрованные данные
        }
Exemple #15
0
        private void button_Decode_Click(object sender, EventArgs e)
        {
            int row;
            int col;
            try
            {
                row = Convert.ToInt32(textBox_Block_Diff_M.Text);
                col = Convert.ToInt32(textBox_Block_Diff_N.Text);
            }
            catch (Exception)
            {
                MessageBox.Show("В полях размера блока введены недопустимые символы");
                return;
            }

            string colorComponent = "R";

            if (radioButton_Red.Checked) colorComponent = "R";
            else if (radioButton_Green.Checked) colorComponent = "G";
            else if (radioButton_Blue.Checked) colorComponent = "B";

            Regex pattern = new Regex(@"^\s*\d+\s*$");

            if (pattern.IsMatch(textBox_Offset.Text) && pattern.IsMatch(textBox_M.Text) && pattern.IsMatch(textBox_N.Text) && Image_Default.Image != null)
            {
                string xSize;
                string ySize;

                if (radioButton_Block_Method.Checked)
                {
                    xSize = textBox_M.Text;
                    ySize = textBox_N.Text;
                }
                else
                {
                    xSize = textBox_Block_Diff_M.Text;
                    ySize = textBox_Block_Diff_N.Text;
                }

                Utils.initialize(imgPath, richTextBoxKey.Text, colorComponent, (textBox_Offset.Text.Length == 0 ? 0 : Convert.ToInt32(textBox_Offset.Text)), (xSize.Length == 0 ? 0 : Convert.ToInt32(xSize)), (ySize.Length == 0 ? 0 : Convert.ToInt32(ySize)));

                data = new PreparedData("decode");

                if (Utils.checkFields("decode"))
                {
                    MessageBox.Show("Одно или более полей - пустые");
                    return;
                }

                //try
                //{
                    if (radioButtonLSB_Static.Checked)
                    {
                        Methods.LeastSignificantBit lsb = new Methods.LeastSignificantBit();

                        message_box.Text = lsb.Decrypt(ref data, Information.key, Information.offset);
                    }
                    else if (radioButton_Block_Method.Checked)
                    {
                        Methods.Block.Block block = new Methods.Block.Block();

                        message_box.Text = block.Decoder(ref data, Information.container.xSize, Information.container.ySize, Information.key);
                    }
                    else if (radioButton_Block_Different_Shape.Checked)
                    {
                        Methods.Block_Different_Shape.Block_Different_Shape block = new Methods.Block_Different_Shape.Block_Different_Shape();

                        General.Point[] selectedPoints = null;
                        General.Point[] notSelectedPoints = null;

                        General.Utils.getShapePoints(row, col, boxes, out selectedPoints, out notSelectedPoints);

                        message_box.Text = block.Decoder(ref data, selectedPoints, notSelectedPoints, Information.container.xSize, Information.container.ySize, Information.key);
                    }

                //}
                //catch (Exception msg)
                //{
                //    MessageBox.Show("Произошли проблемы при шифровании.\n " + msg.Message);
                //    return;
                //}
                MessageBox.Show("Дешифрирование прошло успешно");
            }
        }
        private void getContainers(ref PreparedData data, ref Methods.Block_Different_Shape.Container[] containers, General.Point[] selectedPoints, General.Point[] NotSelectedPoints, int xSize, int ySize, int rowContainers, int colContainers, int limit, int startFrom = 0)
        {
            int index = 0; // индекс контейнера

            int yStart = 0;
            int xStart = 0;

            if (startFrom > 0)
            {
                yStart = startFrom / colContainers;
                xStart = startFrom % colContainers;
            }

            for (int y = yStart * ySize; y < ySize * rowContainers && index < limit; y += ySize)
            {
                for (int x = xStart * xSize; x < xSize * colContainers && index < limit; x += xSize)
                {
                    containers[index] = new Methods.Block_Different_Shape.Container(ref data, selectedPoints, NotSelectedPoints, x, y, xSize, ySize);   // берем текущие кооридинаты и координаты, смещенные относительно
                    index++;
                }
                xStart = 0;
            }
        }
        public void updateValue(bool value, bool block, ref PreparedData data)
        {
            Point[] points;
            if (block) points = this.points_NotChecked;
            else points = this.points_Checked;

            // случайным образом выбираем позицию в контейнере
            Random rnd = new Random();
            int i = rnd.Next(points.Length);

            char[] colorBits = Convert.ToString(data.imgChanel[points[i].y][points[i].x], 2).ToCharArray(); // переводим текущую цветовую компоненту в 2й вид
            if (colorBits[colorBits.Length - 1] == '1') // если последний бит единица
            {
                colorBits[colorBits.Length - 1] = '0';   // записываем в объект 1
            }
            else
            {
                colorBits[colorBits.Length - 1] = '1'; // записываем в объект 0
            }

            data.imgChanel[points[i].y][points[i].x] = Convert.ToInt32(new string(colorBits), 2); // записываем обновленное значение цветовой компоненты в цветовом канале

            if(block) sumBits_NotChecked = value; // обновляем значение в объекте контейнера
            else sumBits_Checked = value; // обновляем значение в объекте контейнера
        }
Exemple #18
0
        // Нужно исправить, чтобы уменьшить количество кода и условий
        public static Bitmap setColorChanel(ref PreparedData data)
        {
            Bitmap img = new Bitmap(data.img);
            Color pixel;

            for (int i = 0; i < data.img.Height; i++)
            {
                for (int j = 0; j < data.img.Width; j++)
                {
                    pixel = img.GetPixel(j, i);
                    Color newPixel = setToChanel(pixel, data.imgChanel, i, j, Information.colorChanel);
                    img.SetPixel(j, i, newPixel);
                    // Here Can be implemented progress bar
                }
            }
            return img;

            throw new Exception("Недопустимая цветовая компонента. Возможные варианты - R, G, B");
        }