
- •VStepanov.CourseWork.First Common.Cs
- •VStepanov.CourseWork.First.Binary BmpInfo.Cs
- •ByteMixer.Cs
- •Relocator.Cs
- •VStepanov.CourseWork.First.Cryptography
- •XorCodec.Cs
- •VStepanov.CourseWork.First.Steganography Steganogram.Cs
- •SteganogramBmp.Cs
- •SteganogramInfo.Cs
- •SteganogramMessage.Cs
- •VStepanov.CourseWork.First.Gui AnimatedForm.Cs
- •FileAddForm.Cs
- •GuiMethods.Cs
- •PasswordRequest.Cs
- •Program.Cs
- •SplashForm.Cs
- •TextAddForm.Cs
- •TextReadForm.Cs
- •Лист регистрации изменений
SteganogramMessage.Cs
using System;
using System.Linq;
using System.Text;
using System.IO;
using VStepanov.CourseWork.First.Cryptography;
namespace VStepanov.CourseWork.First.Steganography
{
/// <summary>
/// Задаёт константы, определяющие тип сообщения.
/// </summary>
[Flags]
public enum MessageType
{
/// <summary>
/// Сообщение содержит текстовые данные.
/// </summary>
Text = 0x01,
/// <summary>
/// Сообщение содержит двоичный файл.
/// </summary>
File = 0x02,
/// <summary>
/// Сообщение зашифровано.
/// </summary>
Encrypted = 0x04
}
/// <summary>
/// Структура, описывающая стеганографическое сообщение.
/// </summary>
public struct SteganogramMessage
{
#region Константы
/// <summary>
/// Число байт для хранения типа сообщения.
/// </summary>
private const int MessageTypeLength = 1;
/// <summary>
/// Число байт для хранения расширения файла.
/// </summary>
private const int FileExtensionLength = 8;
/// <summary>
/// Число байт для хранения информации о сообщении.
/// </summary>
public static readonly int MessageHeaderSize = MessageTypeLength + FileExtensionLength;
#endregion
#region Поля
private string _fileExtension;
/// <summary>
/// Расширение файла. Всегда занимает размер в 8 байт, при необходимости дополняется пробелами слева.
/// </summary>
public string FileExtension
{
get { return _fileExtension; }
set { _fileExtension = value.PadLeft(FileExtensionLength).Substring(0, FileExtensionLength); }
}
/// <summary>
/// Тип сообщения.
/// </summary>
public MessageType MessageType { get; set; }
private byte[] _data;
/// <summary>
/// Байты сообщения.
/// </summary>
public byte[] Data
{
get { return _data.ToArray(); }
private set { _data = value; }
}
#endregion
#region Конструкторы
/// <summary>
/// Создаёт открытое сообщение.
/// </summary>
/// <param name="data">Данные сообщения.</param>
private SteganogramMessage(byte[] data)
{
this = new SteganogramMessage();
Data = data;
}
/// <summary>
/// Создаёт зашифрованное заданным паролем сообщение.
/// </summary>
/// <param name="data">Данные сообщения.</param>
/// <param name="password">Пароль, которым будет зашифровано сообщение.</param>
private SteganogramMessage(byte[] data, string password)
{
this = new SteganogramMessage();
Data = data;
EncryptMessage(password);
}
#region Из строки с сообщением
/// <summary>
/// Создаёт текстовое сообщение.
/// </summary>
/// <param name="s">Текст, подлежащий стеганографированию.</param>
/// <returns>Сообщение, содержащее текст, переданный в параметре s.</returns>
public static SteganogramMessage FromString(string s)
{
byte[] data = Encoding.UTF8.GetBytes(s);
var message = new SteganogramMessage(data);
message.MessageType |= MessageType.Text;
message.FileExtension = String.Empty;
return message;
}
/// <summary>
/// Создаёт зашифрованное паролем текстовое сообщение.
/// </summary>
/// <param name="s">Текст, подлежащий стеганографированию.</param>
/// <param name="password">Пароль, которым будет зашифрованно сообщение.</param>
/// <returns>Сообщение, содержащее текст, переданный в параметре s, зашифрованный паролем password.</returns>
public static SteganogramMessage FromString(string s, string password)
{
byte[] data = Encoding.UTF8.GetBytes(s);
var message = new SteganogramMessage(data, password);
message.MessageType |= MessageType.Text;
message.FileExtension = String.Empty;
return message;
}
#endregion
#region Из файла
/// <summary>
/// Создаёт сообщение, содержащее данные из произвольного файла.
/// </summary>
/// <param name="file">Информация о файле, который необходимо поместить в сообщение.</param>
/// <returns>Сообщение, содержащее данные из файла, заданного параметром file.</returns>
public static SteganogramMessage FromFile(FileInfo file)
{
byte[] data;
using (BinaryReader br = new BinaryReader(file.OpenRead()))
{
data = br.ReadBytes((int)file.Length);
}
var message = new SteganogramMessage(data);
message.MessageType |= MessageType.File;
message.FileExtension = file.Extension;
return message;
}
/// <summary>
/// Создаёт зашифрованное паролем сообщение, содержащее данные из произвольного файла.
/// </summary>
/// <param name="file">Информация о файле, который необходимо поместить в сообщение.</param>
/// <param name="password">Пароль, которым будет зашифрованно сообщение.</param>
/// <returns>Сообщение, содержащее данные из файла, заданного параметром file, зашифрованные паролем password.</returns>
public static SteganogramMessage FromFile(FileInfo file, string password)
{
byte[] data;
using (BinaryReader br = new BinaryReader(file.OpenRead()))
{
data = br.ReadBytes((int)file.Length);
}
var message = new SteganogramMessage(data, password);
message.MessageType |= MessageType.File;
message.FileExtension = file.Extension;
return message;
}
#endregion
#endregion
#region Работа с дампами
/// <summary>
/// Переводит структуру в массив байт, пригодный для записи и обратного конвертирования в структуру.
/// </summary>
/// <param name="steganogramMessage">Структура для перекодировки.</param>
/// <returns>Массив байт, представляющий собой переданную структуру.</returns>
public static byte[] GetBytes(SteganogramMessage steganogramMessage)
{
byte[] data = new byte[MessageHeaderSize + steganogramMessage.Data.Length];
data[0] = (byte)steganogramMessage.MessageType;
Encoding.UTF8.GetBytes(steganogramMessage.FileExtension).CopyTo(data, MessageTypeLength);
steganogramMessage.Data.CopyTo(data, MessageHeaderSize);
return data;
}
/// <summary>
/// Переводит массив байт в структуру.
/// </summary>
/// <param name="bytes">Массив байт, представляющий собой структуру.</param>
/// <returns>Структура SteganogramInfo, восстановленная из переданного массива байт.</returns>
public static SteganogramMessage FromBytes(byte[] bytes)
{
SteganogramMessage message = new SteganogramMessage();
message.MessageType = (MessageType)bytes[0];
message.FileExtension = Encoding.UTF8.GetString(bytes.Skip(MessageTypeLength).Take(FileExtensionLength).ToArray());
message.Data = bytes.Skip(MessageHeaderSize).ToArray();
return message;
}
#endregion
#region Шифровка/дешифровка сообщения
/// <summary>
/// Шифровка сообщения указанным ключом.
/// </summary>
/// <param name="password">Ключ шифрования.</param>
public void EncryptMessage(string password)
{
if (!MessageType.HasFlag(MessageType.Encrypted))
{
Data = XorCodec.Encrypt(Data, password);
MessageType |= MessageType.Encrypted;
}
}
/// <summary>
/// Дешифровка сообщения указанным ключом.
/// </summary>
/// <param name="password">Ключ шифрования.</param>
public void DecryptMessage(string password)
{
if (MessageType.HasFlag(MessageType.Encrypted))
{
Data = XorCodec.Decrypt(Data, password);
MessageType &= ~MessageType.Encrypted;
}
}
#endregion
}
}