/TugasAkhir1/Scramble.cs
C# | 450 lines | 336 code | 58 blank | 56 comment | 44 complexity | 48cda6838582c9d622c654a38780e3ec MD5 | raw file
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Text;
5using System.Threading.Tasks;
6using System.IO;
7using System.Drawing;
8using System.Drawing.Imaging;
9
10
11
12namespace TugasAkhir1
13{
14 /**
15 * This class was used to do some matrix manipulation
16 * 1. ConvertToVectorMatrix Class
17 * 2. ConvertToBinaryVectorMatrix Class
18 * 3. 1/3 Convolution Code
19 * 4. Direct Sequence Spread Spectrum
20 * 5. Interleaving Sequence
21 * 6. Segment
22 * */
23 public class Scramble
24 {
25 //Global Variables
26 static int[] pnseed = new int[5];
27
28 #region 1. ConvertToVectorMatrix
29 //Convert to 1 Dimensional Matrix fill with black and white value
30 public static List<int> ConvertToVectorMatrix(Bitmap bmp)
31 {
32 List<int> m = new List<int>();
33 int width = bmp.Width;
34 int height = bmp.Height;
35 for (int y = 0; y < height; y++)
36 {
37 for (int x = 0; x < width; x++)
38 {
39 Color c = bmp.GetPixel(x, y);
40 int p = (c.R+c.G+c.B)/3;
41 m.Add(p);
42 }
43 }
44
45 return m;
46 }
47 #endregion
48
49 #region 2. ConvertToBinaryVectorMatrix
50 //Convert to 0 or 1 bit sequence , 1 denote to white space and 0 denote to black space
51 public static List<int> ConvertToBinaryVectorMatrix(List<int> vm)
52 {
53 List<int> bvm = new List<int>();
54 foreach (int i in vm)
55 {
56 if (i >= 250)
57 {
58 int b = 1;
59 bvm.Add(b);
60 }
61 else if (i <= 0)
62 {
63 int b = 0;
64 bvm.Add(b);
65 }
66 }
67
68 return bvm;
69 }
70 #endregion
71
72 #region 3. 1/3 Convolution Code
73 /**
74 * 1/3 Convolutional Code
75 * k = 1 , Number of input each time process
76 * n = 3 , number of output each time after process
77 * m = input data
78 * Generator Polynomial use:
79 * g1 = { 1, 1, 1, 1, 0, 1, 1, 1 }
80 * g2 = { 1, 1, 0, 1, 1, 0, 0, 1 }
81 * g3 = { 1, 0, 0, 1, 0, 1, 0, 1 }
82 **/
83 public static List<int> ConvolutionEncoding(List<int> m)
84 {
85 List<int> mc = new List<int>(); //Output list
86 int elm = 0;
87 int v = 3; //1/3 rate with 3 output at a time.
88 //memory register
89 int[] reg = new int[m.Count];
90 //Generator Polynomial
91 int[,] g = new int[,] { { 1, 1, 1, 1, 0, 1, 1, 1 }, //g0
92 { 1, 1, 0, 1, 1, 0, 0, 1 }, //g1
93 { 1, 0, 0, 1, 0, 1, 0, 1 } }; //g2
94
95 for (int n = 0; n < m.Count; n++)
96 {
97 for (int i = 0; i < v/*3*/; i++)
98 {
99 for(int j = 0; j < 8; j++)
100 {
101 int l = n - j;
102 if (l < 0)
103 {
104 elm += g[i,j] * 0; //x[n] = 0 , if n = negative
105 }
106 else
107 {
108 elm += g[i, j] * m[l];
109 }
110 }
111 int item = elm % 2;
112 mc.Add(item);
113 }
114 }
115
116 return mc;
117 }
118 #endregion
119
120 #region 4. Direct Sequence Spread Spectrum
121 /* *
122 * Direct Sequence Spread Spectrum
123 * convert the input binary sequence into sequence with values 1 or 0
124 * 1. Input bit is a binary bit from 1/3 Convolutional Code
125 * 2. The input bit is generated using a PN Sequence
126 * 3. PN Sequence is generated using a key
127 * 4. The result will be a sequence contain values 1 and -1 with length = input bit length * PN Sequence length
128 * */
129 public static List<int> DSSS(List<int> mc, List<int> PNSeq)
130 {
131 List<int> dsss = new List<int>();
132 //int pnlength = mc.Count * 4;
133 ////List<int> PNSeq = PNSeqGenerate(pnlength); //Pseudonoise sequence generated randomly using pseudorandom sequence
134 //string pn_seed = "1000"; //Secret Key K
135 //string pn_mask = "1010";
136 //int pn_length = pnlength;
137 //List<int> PNSeq = PNSeqLFSR(pn_seed, pn_mask, pn_length);
138
139 int k = 0;
140 for (int i = 0; i < mc.Count; i++) //Looping for input data
141 {
142 while(k < (i+1)*5) // Looping for PN sequence, each bit in input data is attach to 5 PN bit sequence
143 {
144 if (mc[i] == 0)
145 {
146 int xor = mc[i] ^ PNSeq[k];
147 dsss.Add(xor);
148 }
149 else
150 {
151 int xor = mc[i] ^ PNSeq[k];
152 dsss.Add(xor);
153 }
154 k = k + 1;
155 }
156 }
157
158 return dsss;
159 }
160
161 //Generate PNSequence using LFSR(Linear Feedback Shift Register)
162 public static List<int> PNSeqLFSR(string seed, string mask, int length)
163 {
164 List<int> pnseq = new List<int>();
165
166 //Initialize shift register with the pn_seed
167 for (int i = 0; i < seed.Length; i++)
168 {
169 pnseed[i] = (int)Char.GetNumericValue(seed[i]);
170 }
171
172 int[] key = pnseed; //key = sr
173
174 for (int i = 0; i < length; i++)
175 {
176 int new_bit = 0;
177 for (int j = 0; j < 5; j++)
178 {
179 if ((int)Char.GetNumericValue(mask[j]) == 1)
180 new_bit = new_bit ^ key[j];
181 }
182
183 pnseq.Add(key[5 - 1]);
184 key = Roll(key);
185 key[0] = new_bit;
186 }
187
188 return pnseq;
189 }
190
191 //Shift pnseed to the right
192 public static int[] Roll(int[] key)
193 {
194 int[] ShiftedKey = new int[key.Length];
195 for (int i = 0; i < key.Length; i++)
196 {
197 ShiftedKey[(i + 1) % ShiftedKey.Length] = key[i];
198 }
199
200 return ShiftedKey;
201 }
202
203 public List<int> PNSeqGenerate(int l)
204 {
205 List<int> pn = new List<int>();
206 Random rnd = new Random();
207 for (int i = 0; i < l; i++)
208 {
209 pn.Add(rnd.Next(2));
210 }
211
212 return pn;
213 }
214 #endregion
215
216 #region 5. Interleaving Sequence
217 public static List<int> Interleaving(List<int> dsss)
218 {
219 List<int> il = new List<int>();
220 var ds3 = dsss;
221 List<int> ySeq = GenerateRandomBinarySeq(ds3.Count);
222 //dsss.AddRange(ySeq);
223 //var InterLength = dsss.Count * 2;
224 //int k1 = 0;
225 //int k2 = InterLength / 2;
226 while (ds3.Count > 0 && ySeq.Count > 0)
227 {
228 if (ds3.Count > 0)
229 {
230 il.Add(ds3[0]);
231 ds3.RemoveAt(0);
232 }
233
234 if (ySeq.Count > 0)
235 {
236 il.Add(ySeq[0]);
237 ySeq.RemoveAt(0);
238 }
239 }
240
241 return il;
242 }
243
244 public static List<int> GenerateRandomBinarySeq(int length) //generate random binary sequence for Interleaving sequence
245 {
246 var randBin = new List<int>();
247 Random rand = new Random();
248
249 for (int i = 0; i < length; i++)
250 {
251 if (rand.Next() % 2 == 0)
252 {
253 randBin.Add(0);
254 }
255 else
256 {
257 randBin.Add(1);
258 }
259 }
260
261 randBin.Sort();
262 return randBin;
263 }
264 #endregion
265
266 #region 6. Segmentation
267 //Group the Interleaved sequence into M-bit segments. M = 5.
268 public static List<List<int>> Segment(List<int> Interleaved)
269 {
270 List<List<int>> Tree = new List<List<int>>();
271 List<int> tree_th = new List<int>();
272
273 //Get total number of trees
274 double t = Interleaved.Count / 5; //5 didapat dari jumlah node dalam 1 pohon HMM, 3 parents dan 12 anak-nya untuk setiap scale.
275 int nSize =(int)Math.Floor(t);
276 double s = Interleaved.Count / nSize;
277 int segSize = (int)s;
278
279 for (int i = 0; i < Interleaved.Count; i += segSize)
280 {
281 Tree.Add(Interleaved.GetRange(i, Math.Min(segSize, Interleaved.Count - i)));
282 }
283
284 return Tree;
285 }
286 #endregion
287
288 #region 7. Mapping the Scrambled Watermark
289 public static double[,] Mapping(List<List<int>> SegmentedWatermark)
290 {
291 double[,] MappedWatermark = new double[SegmentedWatermark.Count,15];
292 for (int i = 0; i < SegmentedWatermark.Count; i++)
293 {
294 int[] repeated_version = SegmentedWatermark[i].ToArray();
295 int[] inversed_version = new int[SegmentedWatermark[i].Count];
296 for (int j = 0; j < SegmentedWatermark[i].Count; j++)
297 {
298 if (SegmentedWatermark[i][j] == 0)
299 {
300 inversed_version[j] = 1;
301 }
302 else
303 {
304 inversed_version[j] = 0;
305 }
306 }
307
308 //Watermark Mapping
309 //Horizontal -> LH : Level 1 and 2
310 MappedWatermark[i,0] = repeated_version[0]; //Triangle #0
311 MappedWatermark[i,1] = repeated_version[3]; //Triangle #3
312 MappedWatermark[i,2] = inversed_version[1]; //Square #1
313 MappedWatermark[i,3] = inversed_version[4]; //Square #4
314 MappedWatermark[i,4] = repeated_version[2]; //Circle #2
315
316 //Diagonal -> HH : Level 1 and 2
317 MappedWatermark[i,5] = repeated_version[1]; //Triangle #1
318 MappedWatermark[i,6] = repeated_version[4]; //Triangle #4
319 MappedWatermark[i,7] = inversed_version[2]; //Square #2
320 MappedWatermark[i,8] = repeated_version[0]; //Circle #0
321 MappedWatermark[i,9] = repeated_version[3]; //Circle #3
322
323 //Vertical -> HL : Level 1 and 2
324 MappedWatermark[i,10] = repeated_version[2]; //Triangle #2
325 MappedWatermark[i,11] = inversed_version[0]; //Square #0
326 MappedWatermark[i,12] = inversed_version[3]; //Square #3
327 MappedWatermark[i,13] = repeated_version[1]; //Circle #1
328 MappedWatermark[i,14] = repeated_version[4]; //Circle #4
329 }
330
331 return MappedWatermark;
332 }
333
334 #endregion
335
336 #region Mapping2 the scrambled watermark
337 public static double[,] Mapping2(List<List<int>> SegmentedWatermark)
338 {
339 double[,] MappedWatermark = new double[SegmentedWatermark.Count, 5];
340 for(int i = 0; i < MappedWatermark.GetLength(0); i++)
341 {
342 for(int j = 0; j < MappedWatermark.GetLength(1); j++)
343 {
344 MappedWatermark[i, j] = SegmentedWatermark[i][j];
345 }
346 }
347 return MappedWatermark;
348 }
349 #endregion
350
351 #region 8. Inverse
352 /// <summary>
353 /// Merge the 5-segment watermark.
354 /// </summary>
355 /// <param name="inversedMapping"></param>
356 /// <returns></returns>
357 public static List<double> MergeSegmentedWatermark(double[,] inversedMapping)
358 {
359 List<double> ScrambledWatermark = new List<double>();
360 for(int i = 0; i < inversedMapping.GetLength(0); i++)
361 {
362 for(int j = 0; j < inversedMapping.GetLength(1); j++)
363 {
364 ScrambledWatermark.Add(inversedMapping[i, j]);
365 }
366 }
367 return ScrambledWatermark;
368 }
369
370 public static List<double> MergeSegmentedWatermark2(double[][] inversedMapping)
371 {
372 List<double> ScrambledWatermark = new List<double>();
373 for (int i = 0; i < inversedMapping.GetLength(0); i++)
374 {
375 for (int j = 0; j < inversedMapping[i].Length; j++)
376 {
377 ScrambledWatermark.Add(inversedMapping[i][j]);
378 }
379 }
380 return ScrambledWatermark;
381 }
382
383 public static List<int> InverseDSSS(List<double> ScrambledWatermark, List<int> PNSeq)
384 {
385 List<int> InversedDSSS = new List<int>();
386 List<int> sWatermark = ScrambledWatermark.ConvertAll(Convert.ToInt32); //Convert list of double into list of integers
387 List<int> xorList = new List<int>();
388
389 List<int> RealWatermark = new List<int>();
390
391 for(int i = 0; i < sWatermark.Count; i++)
392 {
393 xorList.Add(sWatermark[i] ^ PNSeq[i]);
394 }
395
396 List<List<int>> segmentedXOR = SplitList(xorList, 5);
397 for(int i = 0; i < segmentedXOR.Count; i++)
398 {
399 RealWatermark.Add(ReturnMaxItem(segmentedXOR[i]));
400 }
401
402 return RealWatermark;
403 }
404
405 public static List<List<int>> SplitList(List<int> inputlist, int nSize)
406 {
407 var list = new List<List<int>>();
408
409 for (int i = 0; i < inputlist.Count; i += nSize)
410 {
411 list.Add(inputlist.GetRange(i, Math.Min(nSize, inputlist.Count - i)));
412 }
413
414 return list;
415 }
416
417 public static int ReturnMaxItem(List<int> list)
418 {
419 int maxRepeated = list.GroupBy(s => s)
420 .OrderByDescending(s => s.Count())
421 .First().Key;
422
423 return maxRepeated;
424 }
425
426 #endregion
427
428 #region Convert to 1 and -1 watermark value
429 public static List<int> ConvertTo1minus1(List<int> BinaryVectorImage)
430 {
431 List<int> oneminusone = new List<int>();
432 for(int i = 0; i < BinaryVectorImage.Count; i++)
433 {
434 if (BinaryVectorImage[i] == 1)
435 {
436 oneminusone.Add(1);
437 }else
438 {
439 oneminusone.Add(-1);
440 }
441 }
442
443 return oneminusone;
444 }
445
446
447 #endregion
448
449 }
450}