// функция возвращает скрытый текст public static string GetHiddenText(StegoBitmap bitmap, Colours colour) { byte[] txt = bitmap.GetColour(colour); // массив байтов указанного цвета для данного StegoBitmap byte mark = CommonFunc.BoolArrByte(txt.Take(8).SelectMany(e => LastBit(e, 1)).ToArray()); // байт метки byte sizeLen = CommonFunc.BoolArrByte(txt.Skip(8).Take(8).SelectMany(e => LastBit(e, 1)).ToArray()); // байт размера длины bool[] lenBool = txt.Skip(16).Take(sizeLen * 8).SelectMany(e => LastBit(e, 1)).ToArray(); // массив из булевых элементов длины скрытого текста (каждый элемент в отдельном байте) var lenBytes = new List <byte>(); for (int i = 0; i < lenBool.Length; i += 8) { lenBytes.Add(CommonFunc.BoolArrByte(lenBool.Skip(i).Take(8).ToArray())); // список байтов длины (использовуется список, т.к. длина текста может быть разной), добавляем элементы путем прохода по 8 битам, а затем берем следующие восемь } bool[] textBool = txt.Skip(16 + sizeLen * 8).Take(CommonFunc.IntBytes(lenBytes) * 8).SelectMany(x => LastBit(x, 1)).ToArray(); // массив из булевых элементов скрытого текста (каждый элемент в отдельном байте) var textBytes = new List <byte>(); for (int i = 0; i < textBool.Length; i += 8) { textBytes.Add(CommonFunc.BoolArrByte(textBool.Skip(i).Take(8).ToArray())); // список байтов текста, добавляем элементы путем прохода по 8 битам, а затем берем следующие восемь } return(Encoding.GetEncoding(1251).GetString(textBytes.ToArray())); }
// функция находит скрытый текст public static string GetHiddenText(StegoBitmap stgbmap, Colours c) { var bmap = stgbmap.GetImage(); int width = bmap.Width; int height = bmap.Height; var arrWhereHide = new byte[bmap.Width, bmap.Height]; // массив байтов, где будет хранится текст в соотвествии с выбранным цветом //выбираем из изображения пиксели в соответствии с переданным цветом for (int i = 0; i < bmap.Width; i++) { for (int j = 0; j < bmap.Height; j++) { if (c == Colours.Red) { arrWhereHide[i, j] = bmap.GetPixel(i, j).R; } else if (c == Colours.Green) { arrWhereHide[i, j] = bmap.GetPixel(i, j).G; } else if (c == Colours.Blue) { arrWhereHide[i, j] = bmap.GetPixel(i, j).B; } else { throw new NullReferenceException(); } } } int numSegm = bmap.Width * bmap.Height / (SizeSegment * SizeSegment); //общее число сегментов var segm = new List <byte[, ]>(); Separate(arrWhereHide, segm, bmap.Width, bmap.Height, SizeSegment);// разбиваем массив на сегменты // дискретное косинусное преобразование var dctList = new List <double[, ]>(); foreach (var b in segm) { dctList.Add(DCT(b)); // список из коэффициентов ДКП } var txtByte = new List <byte>(); List <int> possibPos = new List <int>(); // возможные позиции в соответствии с размером списка коэффициентов ДКП for (int i = 0; i < dctList.Count; i++) { possibPos.Add(i); } int end = 2; //конец прохода bool LenDone = true; for (int i = 0; i < end; i++) { var bits = new bool[8]; // булевый массив битов символа for (int j = 0; j < 8; j++) { int pos = possibPos[0]; // позиция possibPos.RemoveAt(0); double AbsPoint1 = Math.Abs(dctList[pos][p1.X, p1.Y]); double AbsPoint2 = Math.Abs(dctList[pos][p2.X, p2.Y]); // бит выделяем в соответсвии с тем, какое абслютное значение больше if (AbsPoint1 > AbsPoint2) { bits[j] = false; } else if (AbsPoint1 < AbsPoint2) { bits[j] = true; } } txtByte.Add(CommonFunc.BoolArrByte(bits)); if (i == 0 && txtByte.ToArray()[0] != Convert.ToByte('Z')) // в случае отсутвия метки возвращаем пустую строку { return(""); } else if (i == 1) //увеличиваем конец прохода, узнав размер длины { end = txtByte.ToArray()[1] + 2; txtByte.Clear(); } else if (LenDone && i + 1 == end) //увеличиваем конец прохода, узнав длину { end += CommonFunc.IntBytes(txtByte); txtByte.Clear(); LenDone = false; } } return(Encoding.GetEncoding(1251).GetString(txtByte.ToArray())); //преобразуем массив }
// проверка на налчие скрытого текста public static bool IsHiddenText(StegoBitmap stgbmap, Colours c) { var bmap = stgbmap.GetImage(); int width = bmap.Width; int height = bmap.Height; var arrWhereHide = new byte[bmap.Width, bmap.Height]; // массив байтов, где будет хранится текст в соотвествии с выбранным цветом //выбираем из изображения пиксели в соответствии с переданным цветом for (int i = 0; i < bmap.Width; i++) { for (int j = 0; j < bmap.Height; j++) { if (c == Colours.Red) { arrWhereHide[i, j] = bmap.GetPixel(i, j).R; } else if (c == Colours.Green) { arrWhereHide[i, j] = bmap.GetPixel(i, j).G; } else if (c == Colours.Blue) { arrWhereHide[i, j] = bmap.GetPixel(i, j).B; } else { throw new NullReferenceException(); } } } int numSegm = bmap.Width * bmap.Height / (SizeSegment * SizeSegment); //общее число сегментов var segm = new List <byte[, ]>(); Separate(arrWhereHide, segm, bmap.Width, bmap.Height, SizeSegment);// разбиваем массив на сегменты // дискретное косинусное преобразование var dctList = new List <double[, ]>(); foreach (var b in segm) { dctList.Add(DCT(b)); // список из коэффициентов ДКП } var txtByte = new List <byte>(); List <int> possibPos = new List <int>(); // возможные позиции в соответствии с размером списка коэффициентов ДКП for (int i = 0; i < dctList.Count; i++) { possibPos.Add(i); } var bits = new bool[8]; // булевый массив битов символа for (int j = 0; j < 8; j++) { int pos = possibPos[0]; // позиция possibPos.RemoveAt(0); if (ValidMoonotony(dctList[pos]) && ValidSharpness(dctList[pos])) { double P1 = dctList[pos][p1.X, p1.Y]; double P2 = dctList[pos][p2.X, p2.Y]; double P3 = dctList[pos][p3.X, p3.Y]; //бит выделяем в соответсвии с тем, какое абслютное значение больше if (Math.Min(P1, P2) - P3 >= 0.001) { bits[j] = false; } else if (P3 - Math.Max(P1, P2) >= 0.001) { bits[j] = true; } j++; } j--; } txtByte.Add(CommonFunc.BoolArrByte(bits)); if (txtByte.ToArray()[0] != Convert.ToByte('B')) // в случае отсутвия метки возвращаем пустую строку { return(false); } return(true); }
//функция проверяет наличие метки private static bool Mark(byte[] b) { var arr = b.Take(8).SelectMany(e => LastBit(e, 1)).ToArray(); // для проверки метки используются только первые 8 байтов, в каждом последнем бите которого может находится бит метки 'L' return(CommonFunc.BoolArrByte(arr) == Convert.ToByte('L')); //переводим булев массив в байты и проверяем совпадение с байтовым представлением метки }