Два вопроса по программе, использующую метод LSB Стеганографии. Дело в том, что у меня немного проблемы с понимаем того, зачем нужна та или иная функция, я просто знаю, что так можно делать, поэтому делаю. А когда просят объяснить почему так, то становится сложно.
Как работает вот эта часть программы? (Комментарии приведены в полном коде ниже)
for (i = 0; i < 54; i++)
{
pic = fgetc(q);
fputc(pic, w);
count--;
}
Вопрос касательно части кода, представленной ниже. Почему именно на 2? Моё предположение, что это связано с бинарным представлением массива бит, полученного из изображения.
for (i = 0; i < 24; i++)
{
ff[i] = size2 % 2;
size2 = size2 / 2;
}
Полный код:
#include <stdio.h>
#include <conio.h>
#include <math.h>
#include <clocale>
int main()
{
setlocale(LC_CTYPE, "rus");
FILE *q, *w, *f, *r; // Здесь q - Исходное изображение, f - Исходный текст, w - Зашифрованное изображение, r - расшифрованный текст
int i, j, k, s = 0, count; // i, j, k, s - показатели счётчика
long int size1, size2 = 0, size = 0;
printf("Введите для кодирования - 1, Введите для декодирования - 2: ");
scanf("%d", &i);
if (i == 1)
{
q = fopen("1.bmp", "rb"); // Открываем рисунок
f = fopen("1.txt", "r"); // Открываем текстовый документ с текстом
char e;
while (!feof(f))
{
e = getc(f);
size2++;
}
fclose(f);
f = fopen("1.txt", "r");
w = fopen("2.bmp", "wb");
{
fseek(q, 0, SEEK_END); //Перемещение указателя позиции в потоке в конец
size1 = ftell(q); //Возвращает текущее значение указателя положения в файле для потока. Это значение представляет собой количество байт, на которое указатель отстоит от начала файла. Запоминает это значение в переменной.
fseek(q, 0, SEEK_SET); //Перемещение указателя позиции в потоке в начало
}
count = size1;
bool buf[8], sym[8];
unsigned char pic, temp; // pic - символ исходного изображения, temp - символ для исходного текста
for (i = 0; i < 54; i++) // Начинаем записывать файлы исходного изображения в новое, записываем первые 54 байта, содержащие заголовок файла (40 байт, содержащие идентификатор BMP- файла, его общий размер, а также зарезервированные поля) и заголовок растра (14 байт, содержащие основные характеристики изображения: ширину, высоту, цветовое разрешение, общий размер растровых данных, их положение относительно начала всего файла.)
{
pic = fgetc(q); //Cчитывание символов из потока и сохранение их в виде строки в параметр до тех пор пока не наступит конец строки или пока не будет достигнут конец файла.
fputc(pic, w); //Записывание содержимого символа исходного изображения в заданный поток.
count--;
}
bool ff[24]; //Число 24 здесь обозначет количество бит, у нас есть три цвета: Красный, синий, зелёный, где каждый цвет (пиксель) кодируется 8 битами. 8*3=24.
for (i = 0; i < 24; i++)
{
ff[i] = size2 % 2;
size2 = size2 / 2;
}
for (i = 0; i < 24; i++)
{
pic = fgetc(q);
for (j = 0; j < 8; j++)
{
buf[j] = (int)pic % 2;
pic = (int)pic / 2;
}
buf[0] = ff[i];
i++;
buf[1] = ff[i];
for (j = 0; j < 8; j++) //В одном байте 8 бит
pic = pic + (int)buf[j] * pow(2.0, (int)j);
fputc(pic, w);
count--;
}
while (!feof(f)) //Записываем текст в изображение
{
temp = fgetc(f);
for (i = 0; i < 8; i++)
{
sym[i] = (int)temp % 2;
temp = (int)temp / 2;
}
for (i = 0; i < 8;)
{
pic = fgetc(q);
for (j = 0; j < 8; j++)
{
buf[j] = (int)pic % 2;
pic = (int)pic / 2;
}
pic = 0;
for (k = 0; k < 8; k++, i++)
{
buf[k] = sym[i];
}
for (j = 0; j < 8; j++)
pic = pic + (int)buf[j] * pow(2.0, (int)j);
fputc(pic, w);
count--;
}
s++;
}
while (count)
{
pic = fgetc(q);
fputc(pic, w);
count--;
}
fclose(q);
fclose(f);
fclose(w);
}
else
{printf("Error.\n");}
printf("Завершено.\n");
getch();
return 0;
}
for...
{
ff[i] = size2 % 2;
size2 = size2 / 2;
}
Да, этот фрагмент кода выделяет отдельные биты числа size2 и записывает их в массив. size2[0] соответствует младшему биту. size2 = size2 / 2;
эквивалентно побитовому сдвигу вправо, чтобы на следующем шаге получить очередной бит, который теперь стал младшим
Вот эту
(int)buf[j] * pow(2.0, (int)j)
лучше заменить на
buf[j] * (1 << j)
поскольку использование плавающей арифметики здесь не оправдано, или даже (учитывая, что buf содержит только 0 или 1)
(buf[j] << j)
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
В общем вопрос в заголовке, что за перегружаемый(если уместно применить к этому слово перегружаемый) оператор "" и зачем он используется?
Есть вот такая запись которая применяется ко всей странице,что тут означает запятая?