C# :: Aufgabe #89 :: Lösung #2

3 Lösungen Lösungen öffentlich
#89

Verschlüsseln durch Verstecken

Fortgeschrittener - C# von eulerscheZhl - 27.02.2015 um 18:06 Uhr
Ein Teilgebiet der Kryptographie ist die Steganographie. Hier geht es darum Informationen so zu verstecken, dass andere gar nicht auf die Idee kommen, nach versteckten Informationen zu suchen.

Ein Beispiel, um eine Datei in einem Bild zu verstecken:
Erstelle ein Bytearray mit folgendem Inhalt: die ersten 4 Byte geben die Größe der versteckten Datei in Byte an (big Endian). Danach folgt der Dateiname in ASCII Codierung. Nach einem 0-Byte zu Trennung kommt die zu versteckende Datei selbst.
Diese Daten werden nun in einem Bild versteckt, indem die niederwertigsten beiden Bit eines Pixels für rot, grün und blau überschrieben werden, sodass in jedes Pixel 6 Bit passen. Es wird im oberen linken Eck gestartet und dann die Zeile aufgefüllt, anschließend in der nächsten Zeile fortgefahren.

Das Bild im Anhang wurde auf die beschriebene Weise manipuliert.
Schreibe ein Programm, das die versteckten Daten wieder sichtbar macht.
#2
2 Kommentare
vote_ok
von eulerscheZhl (5230 Punkte) - 06.03.2015 um 17:47 Uhr
Nachdem die erste Lösung eingereicht wurde, kommt hier meine.
Der Code ist übrigens auch im Bildanhang der Aufgabe versteckt.

Quellcode ausblenden C#-Code
using System;
using System.Drawing;
using System.IO;

namespace trainYourProgrammer
{
	class MainClass
	{
		public static void Main(string[] args) {
			string path = "/home/eulerschezahl/Dokumente/Programmieren/challenges/TrainYourProgrammer/";
			//einpacken
			HideFile ((Bitmap)Bitmap.FromFile (path + "Glueckwunsch_org.png"), 
			          new FileInfo (path + "TrainYourProgrammer.zip"))
				.Save(path + "Glueckwunsch.png");
			HideFile ((Bitmap)Bitmap.FromFile (path + "logo.png"), 
			          new FileInfo (path + "Glueckwunsch.png"))
				.Save(path + "Steganographie.png");

			//auspacken zur Probe
			ShowFile ((Bitmap)Bitmap.FromFile (path + "Steganographie.png"), path + "found/");
			ShowFile ((Bitmap)Bitmap.FromFile (path + "Glueckwunsch.png"), path + "found/");
		}

		public static Bitmap HideFile(Bitmap original, FileInfo file) {
			int size = (int)file.Length;
			if (original.Width * original.Height * 6 < (4 + file.Name.Length + 1 + file.Length) * 8)
				throw new NotSupportedException ("file too large for image");
			byte[] byte8 = new byte[4 + file.Name.Length + 1 + file.Length];
			byte8 [0] = (byte)(size >> 24);
			byte8 [1] = (byte)(size >> 16);
			byte8 [2] = (byte)(size >> 8);
			byte8 [3] = (byte)(size);
			for (int i = 0; i < file.Name.Length; i++)
				byte8[i + 4] = (byte)file.Name [i];
			byte[] data = File.ReadAllBytes (file.FullName);
			Array.Copy (data, 0, byte8, 5 + file.Name.Length, data.Length);
			byte[] byte6 = Byte8ToByte6 (byte8);
			Bitmap target = (Bitmap)original.Clone ();
			for (int i = 0; i < byte6.Length; i++) {
				int x = i % target.Width; 
				int y = i / target.Width;
				Color cl = target.GetPixel (x, y);
				cl = Color.FromArgb ((cl.R & 0xFC) | byte6[i] >> 4,
				                     (cl.G & 0xFC) | (byte6[i] >> 2) & 0x3,
				                     (cl.B & 0xFC) | byte6[i] & 0x3);
				target.SetPixel (x, y, cl);
			}
			return target;
		}

		public static void ShowFile(Bitmap bmp, string target) {
			byte[] byte6 = new byte[bmp.Width * bmp.Height];
			for (int i = 0; i < byte6.Length; i++) {
				int x = i % bmp.Width; 
				int y = i / bmp.Width;
				Color cl = bmp.GetPixel (x, y);
				byte6[i] = (byte)((cl.R & 0x3) << 4 | (cl.G & 0x3) << 2 | (cl.B & 0x3));
			}
			byte[] byte8 = Byte6ToByte8 (byte6);

			int size = byte8 [0] << 24 | byte8 [1] << 16 | byte8 [2] << 8 | byte8 [3];
			string filename = "";
			int index = 4;
			do {
				filename += (char)byte8 [index];
			} while (byte8[++index] != 0);
			byte[] file = new byte[size];
			Array.Copy (byte8, index + 1, file, 0, file.Length);
			File.WriteAllBytes (target + filename, file);
		}

		private static byte[] Byte8ToByte6(byte[] byte8) {
			Array.Resize (ref byte8, (byte8.Length / 3 + 2) * 3);
			byte[] byte6 = new byte[(byte8.Length * 4 + 2) / 3];
			for (int i = 0; i < byte8.Length / 3; i++) {
				byte6 [4 * i] = (byte)(byte8 [3 * i] >> 2);
				byte6 [4 * i + 1] = (byte)((byte8 [3 * i] << 4 | byte8 [3 * i + 1] >> 4) & 0x3F);
				byte6 [4 * i + 2] = (byte)((byte8 [3 * i + 1] << 2 | byte8[3*i + 2] >> 6) & 0x3F);
				byte6 [4 * i + 3] =(byte)( byte8 [3 * i + 2] & 0x3F);
			}
			return byte6;
		}

		private static byte[] Byte6ToByte8(byte[] byte6) {
			Array.Resize (ref byte6, (byte6.Length / 4 + 3) * 4);
			byte[] byte8 = new byte[(byte6.Length * 3 + 3) / 4];
			for (int i = 0; i < byte6.Length / 4; i++) {
				byte8 [3 * i] =(byte)( byte6 [4 * i] << 2 | byte6 [4 * i + 1] >> 4);
				byte8 [3 * i + 1] = (byte)(byte6 [4 * i + 1] << 4 | byte6 [4 * i + 2] >> 2);
				byte8 [3 * i + 2] = (byte)(byte6 [4 * i + 2] << 6 | byte6 [4 * i + 3]);
			}
			return byte8;
		}
	}
}

Kommentare:

aheiland

Punkte: 650


18 Lösungen
14 Kommentare

#1
09.03.2015 um 09:01 Uhr
kenn ich schon war in glueckwunsch gepackt
post_arrow
117 0

eulerscheZhl

Punkte: 5230

110 Aufgaben
76 Lösungen
64 Kommentare

#2
09.03.2015 um 15:55 Uhr
Ich weiß, aber ich wollte deinen Code sehen. Das geht nämlich erst, nachdem auch ich eine Lösung eingereicht habe ;)
post_arrow
119 0
Bitte melden Sie sich an um eine Kommentar zu schreiben.
Kommentar schreiben
2102077

Du scheinst einen AdBlocker zu nutzen. Ich würde mich freuen, wenn du ihn auf dieser Seite deaktivierst und dich davon überzeugst, dass die Werbung hier nicht störend ist.