Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ОИБ Lab6.doc
Скачиваний:
2
Добавлен:
24.09.2019
Размер:
110.59 Кб
Скачать

4. Выводы

Компьютерные технологии придали новый импульс развитию и совершенствованию стеганографии, появилось новое направление в области защиты информации — компьютерная стеганография (КС).

Современный прогресс в области глобальных компьютерных сетей и средств мультимедиа привел к разработке новых методов, предназначенных для обеспечения безопасности передачи данных по каналам телекоммуникаций и использования их в необъявленных целях. Эти методы, учитывая естественные неточности устройств оцифровки и избыточность аналогового видео или аудио сигнала, позволяют скрывать сообщения в компьютерных файлах (контейнерах). Причем, в отличие от криптографии, данные методы скрывают сам факт передачи информации.

Еще одной областью использования стеганографии является защита авторского права от пиратства. На компьютерные графические изображения наносится специальная метка, которая остается невидимой для глаз, но распознается специальным ПО. Такое программное обеспечение уже используется в компьютерных версиях некоторых журналов. Данное направление стеганографии предназначено не только для обработки изображений, но и для файлов с аудио- и видеоинформацией и призвано обеспечить защиту интеллектуальной собственности.

Приложение

Исходные тексты программ

#include "stdafx.h"

#include <atlapp.h>

#include <atlgdi.h>

#include <atlfile.h>

#include <vector>

#define GETBIT(Byte, nBit) (BYTE)( (Byte & (1 << nBit)) >> nBit)

#define SETBIT(Byte, Bit, nBit) (BYTE)( ((BYTE)Byte & ( ~((BYTE)1 << nBit) ) ) | ((BYTE)Bit << nBit))

//////////////////////////////////////////////////////////////////////////

struct TBMP

{std::vector<BYTE> buf;

};

struct STEGA_PARAMS

{ int nReplacedBitsCount;

};

//////////////////////////////////////////////////////////////////////////

DWORD LoadBitmap(TBMP &bmp, const TCHAR *pszPath)

{

FILE* fin = _tfopen( pszPath, _T("rb") );

if( fin == 0 )

return ERROR_FILE_NOT_FOUND;

// получим размер файла

fseek(fin, 0, SEEK_END);

long lSize = ftell(fin);

fseek(fin, 0, SEEK_SET);

// выделяем нужное кол-во памяти и читаем

bmp.buf.resize(lSize);

fread( &bmp.buf[0], 1, lSize, fin );

fclose(fin);

return ERROR_SUCCESS;

}

DWORD SaveBitmap(const TBMP &bmp, LPCTSTR pszPath)

{

FILE* fout = _tfopen( pszPath, _T("wb") );

if( fout == 0 )

return ERROR_FILE_INVALID;

fwrite( &bmp.buf[0], 1, bmp.buf.size(), fout );

fclose(fout);

return ERROR_SUCCESS;

}

// получить бит из массива байтов

BYTE GetBit(BYTE *pBuffer, UINT nIndex)

{ UINT nByteIndex = nIndex / 8;//номер байта в буфере (где лежит этот бит)

UINT nBitIndex = nIndex % 8; // номер этого бита в этом байте

return GETBIT(pBuffer[nByteIndex], nBitIndex);

}

// записать бит в массив байтов

void SetBit(BYTE *pBuffer, BYTE bit, UINT nIndex)

{

UINT nByteIndex = nIndex / 8;/ номер байта в буфере (где лежит этот бит)

UINT nBitIndex = nIndex % 8; //номер этого бита в этом байте

pBuffer[nByteIndex] = SETBIT(pBuffer[nByteIndex], bit, nBitIndex);

}

// записать бит в массив байтов с учетом параметров STEGA_PARAMS

void SaveBit(BYTE *pBitmap, BYTE bit, UINT nIndex, const STEGA_PARAMS &params)

{

UINT nByteIndex = nIndex / params.nReplacedBitsCount;

UINT nBitIndex = nIndex % params.nReplacedBitsCount;

pBitmap[nByteIndex] = SETBIT(pBitmap[nByteIndex], bit, nBitIndex);

}

// прочитать бит из массив байтов с учетом параметров STEGA_PARAMS

BYTE LoadBit(BYTE *pBitmap, UINT nIndex, const STEGA_PARAMS &params)

{

UINT nByteIndex = nIndex / params.nReplacedBitsCount;

UINT nBitIndex = nIndex % params.nReplacedBitsCount;

return GETBIT(pBitmap[nByteIndex], nBitIndex);

}

// ёмкость картинки (сколько бит мы туда сможем вписать при заданных параметрах)

UINT GetBmpBitsCapacity(BITMAPINFOHEADER* pBmih, const STEGA_PARAMS &params)

{

// проверить размер

SIZE size;

size.cx = pBmih->biWidth;

size.cy = pBmih->biHeight;

UINT nBmpPixelsCount = size.cx * size.cy; // размер картинки в пикселяхъ

UINT nBmpBytesCount = nBmpPixelsCount * 3; // размер картинки в байтахъ

return nBmpBytesCount * params.nReplacedBitsCount; // ёмкость картинки (сколько бит мы туда сможем вписать при заданных параметрах)

}

void GetBMPInfo(TBMP &bmp,

BITMAPINFOHEADER **ppBmih,

BYTE **ppBytes)

{

BITMAPFILEHEADER *pBmfh = (BITMAPFILEHEADER*)&bmp.buf[0];

BITMAPINFO *pBmi = (BITMAPINFO*)&bmp.buf[sizeof(BITMAPFILEHEADER)];

*ppBmih = &pBmi->bmiHeader;

*ppBytes = &bmp.buf[pBmfh->bfOffBits];

}

DWORD SaveBufferToBmp(TBMP &bmp, const std::vector<BYTE> &vBuffer, const STEGA_PARAMS &params)

{

BITMAPINFOHEADER* pBmih;

BYTE *pBitmap;

GetBMPInfo(bmp, &pBmih, &pBitmap);

// проверить размер

UINT nBmpBitsCapcity = GetBmpBitsCapacity(pBmih, params); // ёмкость картинки (сколько бит мы туда сможем вписать при заданных параметрах)

unsigned long nBufSize = vBuffer.size();

UINT nBufBitsCount = (sizeof(nBufSize) + nBufSize) * 8; // сколько бит надо сохранить (из буфера)

if (nBmpBitsCapcity < nBufBitsCount)

return ERROR_BUFFER_OVERFLOW;

// номер записываемого бита

UINT i = 0;

// сначала побитово сохраняем размер сообщения

for (UINT n = 0; n < sizeof(nBufSize) * 8; n++, i++)

{ BYTE bit = GetBit( (BYTE*) &nBufSize, n);

SaveBit(pBitmap, bit, i, params);

}

// потом каждый бит сообщения

for (UINT n = 0; n < vBuffer.size() * 8; n++, i++)

{ BYTE bit = GetBit( (BYTE*) &vBuffer[0], n);

SaveBit(pBitmap, bit, i, params);

}

return ERROR_SUCCESS;

}

DWORD ReadBufferFromBmp(TBMP &bmp, std::vector<BYTE> &vBuffer, const STEGA_PARAMS &params)

{

BITMAPINFOHEADER* pBmih;

BYTE *pBitmap;

GetBMPInfo(bmp, &pBmih, &pBitmap);

UINT nBmpBitsCapcity = GetBmpBitsCapacity(pBmih, params); // ёмкость картинки (сколько бит мы туда сможем вписать при заданных параметрах)

// сначала пытаемся прочитать размер нашего сообщения

unsigned long nBufSize = 0;

// проверим размер

if (nBmpBitsCapcity < sizeof(nBufSize) * 8)

return ERROR_BUFFER_OVERFLOW;

// номер прочитываемого бита

UINT i = 0;

// побитово читаем длину сообщения

for (UINT n = 0; n < sizeof(nBufSize) * 8; n++, i++)

{ BYTE bit = LoadBit(pBitmap, i, params);

SetBit( (BYTE*)&nBufSize, bit, n);

}

// попытаемся прочитать сообщение

UINT nBufBitsCount = (sizeof(nBufSize) + nBufSize) * 8; // сколько бит надо сохранить (из буфера)

if (nBmpBitsCapcity < nBufBitsCount)

return ERROR_BUFFER_OVERFLOW;

vBuffer.resize(nBufSize);

// побитово читаем сообщение

for (UINT n = 0; n < nBufSize * 8; n++, i++)

{ BYTE bit = LoadBit(pBitmap, i, params);

SetBit(&vBuffer[0], bit, n);

}

return ERROR_SUCCESS;

}

int Code(TCHAR *szCodedFileName, TCHAR *szOutputBMPFileName, const STEGA_PARAMS &params)

{ // открываем кодируемый файл

FILE *fin = _tfopen(szCodedFileName, _T("rb"));

if (!fin)

{ printf("Error: unable to open coded-file.\n");

return 2;

}

// узнали его размер

long nFileSize;

fseek(fin, 0, SEEK_END);

nFileSize = ftell(fin);

fseek(fin, 0, SEEK_SET);

// выделяем буфер, копируем туда название файла, его размер и содержимое

unsigned long nFileNameSize = _tcslen(szCodedFileName) * sizeof(TCHAR);

std::vector<BYTE> vBuffer(sizeof(nFileNameSize) + nFileNameSize + sizeof(nFileSize) + nFileSize);

BYTE *pBuffer = &vBuffer[0];

memcpy(pBuffer, &nFileNameSize, sizeof(nFileNameSize));

pBuffer += sizeof(nFileNameSize);

memcpy(pBuffer, szCodedFileName, nFileNameSize);

pBuffer += nFileNameSize;

memcpy(pBuffer, &nFileSize, sizeof(nFileSize));

pBuffer += sizeof(nFileSize);

fread(pBuffer, 1, nFileSize, fin);

fclose(fin);

// прячем его в BMP

DWORD dwError;

TBMP bmp;

dwError = LoadBitmap(bmp, szOutputBMPFileName);

if (dwError != ERROR_SUCCESS)

{ printf("Error: unable to open bmp-file.\n");

return 4;

}

dwError = SaveBufferToBmp(bmp, vBuffer, params);

if (dwError != ERROR_SUCCESS)

{printf("Error: unable to save coded-file into output-file. Insufficient bmp size.\n");

return 5;

}

dwError = SaveBitmap(bmp, szOutputBMPFileName);

if (dwError != ERROR_SUCCESS)

{ printf("Error: unable to save coded-file.\n");

return 5;

}

return 0;

}

int Decode(TCHAR *szOutputBMPFileName, const STEGA_PARAMS &params)

{

DWORD dwError;

TBMP bmp;

dwError = LoadBitmap(bmp, szOutputBMPFileName);

if (dwError != ERROR_SUCCESS)

{ printf("Error: unable to open bmp-file.\n");

return 2;

}

std::vector<BYTE> vBuffer;

dwError = ReadBufferFromBmp(bmp, vBuffer, params);

if (dwError != ERROR_SUCCESS)

{ printf("Error: unable save coded-file from bmp-file. Incorrect bmp-file.\n");

return 3;

}

// теперь исходный буфер прочитан, сохраним его в файл

BYTE *pBuffer = &vBuffer[0];

unsigned long nFileNameSize;

TCHAR szCodedFileName[MAX_PATH];

memcpy(&nFileNameSize, pBuffer, sizeof(nFileNameSize));

pBuffer += sizeof(nFileNameSize);

memcpy(szCodedFileName, pBuffer, nFileNameSize);

szCodedFileName[nFileNameSize / sizeof(TCHAR)] = _T('\0');

FILE *fout;

fout = _tfopen(szCodedFileName, _T("wb"));

if (!fout)

{ printf("Error: unable to save decoded-file.\n");

return 4;

}

long nFileSize;

pBuffer += nFileNameSize;

memcpy(&nFileSize, pBuffer, sizeof(nFileSize));

pBuffer += sizeof(nFileSize);

fwrite(pBuffer, 1, nFileSize, fout);

fclose(fout);

return 0;

}

//////////////////////////////////////////////////////////////////////////

int _tmain(int argc, TCHAR* argv[])

{ if(argc < 5)

{ printf("Error: arguments missing (mode(c/d), coded-file, bmp-file, code-bits-count).\n");

return 1;

}

// читаем аргументы командной строки

TCHAR cMode;

if (_stscanf(argv[1], _T("%c"), &cMode) == 0)

cMode = 0;

if ((cMode != _T('c')) && (cMode != _T('d')))

{ printf("Error: invalid mode.\n");

return 1;

}

STEGA_PARAMS params;

if (_stscanf(argv[4], _T("%d"), &params.nReplacedBitsCount) == 0)

{ printf("Error: invalid code-bits-count.\n");

return 3;

}

// выполняем нужное действие

if (cMode == _T('c'))

return Code(argv[2], argv[3], params);

return Decode(argv[2], params);

}

11

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]