using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Threading.Tasks;
public static void Main()
public byte K { get; private set; }
public byte[] KArray { get; private set; }
public Key(byte k) : this(k, (byte)new Random().Next(1, 256)) { }
public Key(byte k, byte k0)
KArray = new byte[2 * K];
private void GenerateKey(byte k0)
string str = string.Empty;
for (int i = 1; i < KArray.Length; i++)
str = (KArray[i - 1] * KArray[i - 1]).ToString().Substring(0, 3);
if (int.Parse(str) > 255)
KArray[i] = Convert.ToByte(str.Substring(0, 2));
KArray[i] = Convert.ToByte(str);
private static double ToYUV_Y(Color c)
return 0.299 * c.R + 0.587 * c.G + 0.114 * c.B;
public static Bitmap Embed(Bitmap image, string message, Parameters p)
var msg = Encoding.GetEncoding(1251).GetBytes(message);
int y = image.Height, x = image.Width;
if (x % 8 != 0) x -= x % 8;
if (y % 8 != 0) y -= y % 8;
double[,] _Y = new double[x, y];
Byte[,] B = new Byte[x, y];
for (int i = 0; i < x; i++)
for (int j = 0; j < y; j++)
pixel = image.GetPixel(i, j);
_Y[i, j] = ToYUV_Y(pixel);
var xx = msg.Select(z => new Bits(z)).SelectMany(f => f.ToString().ToCharArray())
.Select(g => Convert.ToInt32(g.ToString()))
double[,] newB = new double[x, y];
Array.Copy(B, newB, B.Length);
for (int i = 0; i < tay * xx.Length; i++)
X = (int)Math.Floor((double)i / y) + 1;
for (int s = 0; s < key.K; s++)
X = (X + Bits.xor(new Bits(key.KArray[2 * s]),
new Bits(Y)).Number) % x + 1;
Y = (Y + Bits.xor(new Bits(key.KArray[2 * s + 1]),
new Bits(X)).Number) % y + 1;
int j = (int)Math.Ceiling((double)(i + 1) / tay);
newB[X, Y] = B[X, Y] + (2 * xx[j - 1] - 1) * v * _Y[X, Y];
if (newB[X, Y] > 255) newB[X, Y] = 255;
if (newB[X, Y] < 0) newB[X, Y] = 0;
for (int i = 0; i < x; i++)
for (int j = 0; j < y; j++)
Color r = image.GetPixel(i, j);
image2.SetPixel(i, j, Color.FromArgb(r.R, r.G, (byte)Math.Round(newB[i, j])));
public static string Extract(Bitmap image, Parameters p)
int y = image.Height, x = image.Width;
Byte[,] B = new Byte[x, y];
for (int i = 0; i < x; i++)
for (int j = 0; j < y; j++)
B[i, j] = image.GetPixel(i, j).B;
List<double> B2 = new List<double>();
List<double> B2o = new List<double>();
List<int> message = new List<int>();
for (int i = 0; i < x * y; i++)
B2 = new List<double>(tay);
B2o = new List<double>(tay);
X = (int)Math.Floor((double)i / y) + 1;
for (int s = 0; s < key.K; s++)
X = (X + Bits.xor(new Bits(key.KArray[2 * s]),
new Bits(Y)).Number) % x + 1;
Y = (Y + Bits.xor(new Bits(key.KArray[2 * s + 1]),
new Bits(X)).Number) % y + 1;
if (sigm < X && X < x - sigm)
if (sigm < Y && Y < y - sigm)
for (int a = s1; a <= s2; a++)
for (int a = s3; a <= s4; a++)
sum /= (s2 - s1 + s4 - s3);
double delta = B2.Select((f, ind) => f - B2o[ind]).Sum() / tay;
int j = (int)Math.Ceiling((double)(i + 1) / tay);
string M1 = string.Join("", message);
byte[] msg = new byte[M1.Length / 8];
for (int i = 0; i < msg.Length; i++)
var temp = new Bits(M1.Substring(8 * (i + 1) - 8, 8));
msg[i] = (byte)temp.Number;
return Encoding.GetEncoding(1251).GetString(msg);
public double v { get; set; }
public int tay { get; set; }
public Key key { get; set; }
private ArrayList bits = new ArrayList();
private int len = 0, num = 0;
num = (int)value; ToBits();
num = (int)value; ToBits();
public Bits(string value)
for (int i = 0; i < len; i++)
if (value[i] == '0') bits.Add(0);
ToInt(); return (char)num;
if (i >= 0 && i < len) return (int)bits[i];
if (value > 0) bits[i] = 1;
public void Add(object value)
if ((int)value == 0) bits.Add(0);
public void Insert(int index, object value)
if (index < 0 || index > len) return;
if (value.Equals(0)) bits.Insert(index, 0);
else bits.Insert(index, 1);
public void Erase(int index)
if (index < 0 || index > len) return;
bits.RemoveAt(index); len--;
for (int i = 0; i < len; i++)
if (bits[i].Equals(0)) bits[i] = 1;
public override string ToString()
for (int i = 0; i < len; i++)
str += bits[i].ToString();
for (int i = 1; i < len - 1; i++)
tmp = bits[i + 1]; bits[i + 1] = bits[i]; bits[i] = tmp;
tmp = bits[0]; bits[0] = bits[len - 1]; bits[len - 1] = tmp;
tmp = bits[0]; bits[0] = bits[len - 1]; bits[len - 1] = tmp;
for (int i = len - 2; i != 0; i--)
tmp = bits[i]; bits[i] = bits[i + 1]; bits[i + 1] = tmp;
for (int i = 0; i < 8; i++)
bits.Add(temp % 2); temp = (int)Math.Floor((double)temp / 2);
len = bits.Count; bits.Reverse();
for (int i = 0; i < len; i++)
if (bits[len - i - 1].Equals(1))
num += (int)Math.Pow(2, i);
public static Bits xor(Bits a, Bits b)
for (int i = 0; i < a.Length; i++)