Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Лаб. 3 ЗИ

.docx
Скачиваний:
0
Добавлен:
29.05.2025
Размер:
158.39 Кб
Скачать

Лабораторная работа #3

#include <iostream>

#include <vector>

#include <cstdint>

#include <windows.h>

#include <locale>

#include <codecvt>

using namespace std;

void print_binary(uint8_t byte);

void hide_byte_into_pixel(RGBQUAD* pixel, uint8_t hide_byte);

uint8_t extract_byte_from_pixel(RGBQUAD& pixel);

void read_file(wstring& file_name, vector<char>& buffer) {

HANDLE hFile = CreateFile(file_name.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

if (hFile == INVALID_HANDLE_VALUE) {

cout << "Ошибка при открытии файла для чтения!" << endl;

return;

}

DWORD fileSize = GetFileSize(hFile, NULL);

buffer.resize(fileSize);

DWORD bytesRead;

ReadFile(hFile, buffer.data(), fileSize, &bytesRead, NULL);

CloseHandle(hFile);

}

void write_file(wstring& file_name, vector<char>& buffer) {

HANDLE hFile = CreateFile(file_name.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

if (hFile == INVALID_HANDLE_VALUE) {

cout << "Ошибка при открытии файла для записи!" << endl;

return;

}

DWORD bytesWritten;

WriteFile(hFile, buffer.data(), buffer.size(), &bytesWritten, NULL);

CloseHandle(hFile);

}

void read_bmp(wstring& bmp_file_name, vector<char>& buffer) {

HANDLE hFile = CreateFile(bmp_file_name.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

if (hFile == INVALID_HANDLE_VALUE) {

cout << "Ошибка при открытии BMP файла для чтения!" << endl;

return;

}

DWORD fileSize = GetFileSize(hFile, NULL);

buffer.resize(fileSize);

DWORD bytesRead;

ReadFile(hFile, buffer.data(), fileSize, &bytesRead, NULL);

CloseHandle(hFile);

}

void write_bmp(wstring& bmp_file_name, vector<char>& buffer) {

HANDLE hFile = CreateFile(bmp_file_name.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

if (hFile == INVALID_HANDLE_VALUE) {

cout << "Ошибка при открытии BMP файла для записи!" << endl;

return;

}

DWORD bytesWritten;

WriteFile(hFile, buffer.data(), buffer.size(), &bytesWritten, NULL);

CloseHandle(hFile);

}

// Функция для печати байта в бинарном формате

void print_binary(uint8_t byte) {

for (int i = 7; i >= 0; --i) {

cout << ((byte >> i) & 0x1);

}

}

// Функция для кодирования сообщения в BMP

void encode_message_to_bmp(string& text_file_name, string& bmp_file_name, string& output_bmp_file_name) {

wstring_convert<codecvt_utf8<wchar_t>> converter;

wstring wide_text_file_name = converter.from_bytes(text_file_name);

wstring wide_bmp_file_name = converter.from_bytes(bmp_file_name);

wstring wide_output_bmp_file_name = converter.from_bytes(output_bmp_file_name);

// Чтение текста

vector<char> message_buffer;

read_file(wide_text_file_name, message_buffer);

string message(message_buffer.begin(), message_buffer.end());

message.push_back(0xFF); // Завершающий байт для конца сообщения

// Чтение BMP файла

vector<char> bmp_buffer;

read_bmp(wide_bmp_file_name, bmp_buffer);

// Запись BMP в новый файл

write_bmp(wide_output_bmp_file_name, bmp_buffer);

// Изменение содержимого BMP

HANDLE hFile = CreateFile(wide_output_bmp_file_name.c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

if (hFile == INVALID_HANDLE_VALUE) {

cout << "Не удалось открыть BMP файл для модификации!" << endl;

return;

}

// Чтение заголовков BMP

DWORD bytesRead;

DWORD fileSize = GetFileSize(hFile, NULL);

vector<char> fileBuffer(fileSize);

SetFilePointer(hFile, 0, NULL, FILE_BEGIN);

//read_bmp(wide_output_bmp_file_name, fileBuffer);

ReadFile(hFile, fileBuffer.data(), fileSize, &bytesRead, NULL);

BITMAPFILEHEADER bmpHeader;

memcpy(&bmpHeader, fileBuffer.data(), sizeof(bmpHeader));

BITMAPINFOHEADER dibHeader;

memcpy(&dibHeader, fileBuffer.data() + sizeof(bmpHeader), sizeof(dibHeader));

DWORD offset = bmpHeader.bfOffBits; // Место начала пикселей

RGBQUAD pixel;

size_t message_index = 0;

// Модификация BMP

while (offset < fileSize && message_index < message.size()) {

memcpy(&pixel, fileBuffer.data() + offset, sizeof(pixel)); // Получаем пиксель из буффера

hide_byte_into_pixel(&pixel, message[message_index]);

memcpy(fileBuffer.data() + offset, &pixel, sizeof(pixel)); // Запись изменённого пикселя обратно в буфер

offset += sizeof(pixel);

message_index++;

}

// Запись измененного BMP в файл

SetFilePointer(hFile, 0, NULL, FILE_BEGIN);

//write_bmp(wide_output_bmp_file_name, fileBuffer);

WriteFile(hFile, fileBuffer.data(), fileSize, &bytesRead, NULL);

CloseHandle(hFile);

cout << "Сообщение закодировано в новый файл: " << output_bmp_file_name << endl;

}

// Функция для извлечения сообщения из BMP

void extract_message_from_bmp(string& file_name) {

wstring_convert<codecvt_utf8<wchar_t>> converter;

wstring wide_file_name = converter.from_bytes(file_name);

vector<char> file_buffer;

read_bmp(wide_file_name, file_buffer);

BITMAPFILEHEADER bmpHeader;

memcpy(&bmpHeader, file_buffer.data(), sizeof(bmpHeader));

BITMAPINFOHEADER dibHeader;

memcpy(&dibHeader, file_buffer.data() + sizeof(bmpHeader), sizeof(dibHeader));

DWORD offset = bmpHeader.bfOffBits; // Место начала пикселей

vector<uint8_t> message;

RGBQUAD pixel;

for (size_t i = offset; i < file_buffer.size(); i += sizeof(pixel)) {

memcpy(&pixel, file_buffer.data() + i, sizeof(pixel)); // Получаем пиксель из буффера

uint8_t byte = extract_byte_from_pixel(pixel);

if (byte == 0xFF) {

break;

}

message.push_back(byte);

}

// Декодирование сообщения

string decoded_message(message.begin(), message.end());

cout << "Извлеченное сообщение: " << endl;

cout << decoded_message << endl;

}

// Функция для скрытия байта в пикселе

void hide_byte_into_pixel(RGBQUAD* pixel, uint8_t hide_byte) {

//RGBQUAD new_pixel = pixel;

pixel->rgbBlue &= 0xFC; // очистка 2 младших бит

pixel->rgbBlue |= (hide_byte >> 6) & 0x03;

pixel->rgbGreen &= 0xFC;

pixel->rgbGreen |= (hide_byte >> 4) & 0x03;

pixel->rgbRed &= 0xFC;

pixel->rgbRed |= (hide_byte >> 2) & 0x03;

pixel->rgbReserved &= 0xFC;

pixel->rgbReserved |= hide_byte & 0x03;

//return new_pixel;

}

// Функция для извлечения байта из пикселя

uint8_t extract_byte_from_pixel(RGBQUAD& pixel) {

uint8_t byte = 0;

byte |= (pixel.rgbBlue & 0x3) << 6;

byte |= (pixel.rgbGreen & 0x3) << 4;

byte |= (pixel.rgbRed & 0x3) << 2;

byte |= (pixel.rgbReserved & 0x3);

return byte;

}

int main() {

//setlocale(LC_ALL, "Russian");

setlocale(LC_ALL, "ru_RU.utf8");

string text_file_name = "lab2_source.txt";

//string bmp_file_name = "chess16-24.bmp";

string bmp_file_name = "source_1920_1280.bmp";

string output_bmp_file_name = "encoded_image.bmp";

encode_message_to_bmp(text_file_name, bmp_file_name, output_bmp_file_name);

string file_name = "encoded_image.bmp";

//string file_name = "1.bmp";

extract_message_from_bmp(file_name);

return 0;

}

Соседние файлы в предмете Защита информации