Member 13443867 Ответов: 2

Как я...impement изображения стеганография в C, используя алгоритм ЛСБ?


Может ли кто-нибудь помочь мне с моим проектом, основанным на стеганографии изображений только на языке Си? Мне нужно использовать алгоритм наименьших значащих битов, чтобы скрыть пользовательские данные в BMP-изображении. Я знаю, что это за алгоритм, но не понимаю, как его реализовать.

Пожалуйста, помогите мне зашифровать данные в BMP-образ с помощью техники LSB на языке Си.


LSB algo:

Буква "А" имеет код ASCII 65 (десятичный),
это 01000001 в двоичном формате.
Для этого потребуется три последовательных пикселя.
24-битное изображение для хранения буквы "А":
Допустим, что пиксели перед вставкой:

      R       G       B
P1-10000000.10100100.10110101,
P2-10110101.11110011.10110111,
P3-11100111.10110011.00110011

Тогда их значения после вставки буквы "А" будут равны:
10000000.10100101.10110100,
10110100.11110010.10110110, 
11100110.10110011.00110011


Что я уже пробовал:

#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
#include<math.h>
#include<string.h>

 long asciiToBinary(int n);
 

 long asciiToBinary(int n) {
    int remainder; 
 long binary = 0, i = 1;
   while(n != 0) {
        remainder = n%2;
        n = n/2;
        binary= binary + (remainder*i);
        i = i*10;
                 }
    return binary;
                           }


typedef struct {
   unsigned int width;
   unsigned int height;
   unsigned int size;
} BITMAPINFOHEADER;

 typedef struct {
   unsigned char blue;
   unsigned char green;
   unsigned char red;
   
} PIXEL;


int main(){
    FILE *image;
    char fpath[1000],mydata[100];
	BITMAPINFOHEADER bih;
    int i=0,b[8],g[8],r[8];
    double asciiTobinary;
    printf("Enter BMP file path");
    scanf("%s",fpath);
   
                       
                                       
    image=fopen(fpath,"rb");
    while(image==NULL){
     printf("Error! Enter path again:");
        scanf("%s",fpath);
                     }

    fseek(image,2,SEEK_SET);                                                //reading the height and width
    fread(&bih.size,4,1,image);
    printf("\n \n Size of the image=%d\n",bih.size);
    fseek(image,18,SEEK_SET);
    fread(&bih.width,4,1,image);
    fseek(image,22,SEEK_SET);
    fread(&bih.height,4,1,image);
    printf("\n \n Width of the image =%d \n Height of the image =%d \n pixel =  b    |    g     |     r \n \n",bih.width,bih.height);

     PIXEL pic[bih.width*bih.height*2],p; 
     
      while(!feof(image)){                                                 //reading the pixels rgb values
      fread(&p.blue,sizeof(p.blue),1,image);                              
      fread(&p.green,sizeof(p.green),1,image);
      fread(&p.red,sizeof(p.red),1,image);
      pic[i]=p;
      printf(" %d=   %u    |     %u    |      %u  ",i+54,pic[i].blue,pic[i].green,pic[i].red);
      
                                                         
      i++;
                       }
                     
                       
                       
                      
     fclose(image);
     return 0;
}

Member 12835561

ответ для приведенного выше кода

2 Ответов

Рейтинг:
6

CPallini

Цитата:
структура typedef {
неподписанные символ синий;
неподписанные символ зеленый;
неподписанные символ красный;
unsigned char bluearray[8];
unsigned char greenarray[8];
unsigned char redarray[8];
} ПИКСЕЛЬ;

С какой целью bluearray, greenarray, redarray члены? Думаю, они тебе не нужны.
Вы также должны убедиться, что входное изображение использует 24 бита на пиксель и правильно обрабатывает шаг (см. Формат файла BMP-Википедия[^]).

Как только у вас есть байты изображения, процесс стеганографии прост, начиная с первого байта изображения, скажем b[n] с n=0, и значение для хранения, скажем v
  1. если (в & 0х80) тогда B[N], где |= 0х01 еще б[п] &ампер;=0xF7
  2. v <<= 1; ++n
  3. если (n< 0), то goto 1
  4. comlpeted


Рейтинг:
18

OriginalGriff

Во-первых, это плохая идея использовать пробел, чтобы отделить путь от данных: что, если путь начинается с "C:\Users\MyName\My документы\..."?
Извлеките путь и данные в двух отдельных строках и используйте отдельные подсказки для каждой из них (и убедитесь, что путь правильный, прежде чем запрашивать данные).

Это твое домашнее задание, а не мое - так что я не дам тебе никакого кода!

Но ... как бы вы это ни делали, вам нужны два файла: один входной, один выходной - так что добавьте второе приглашение для назначения и откройте для этого записываемый файл. Когда вы читаете входной файл, вам нужно скопировать данные в выходной файл, изменив только пиксельные данные - это важно, потому что без информации заголовка ваш новый файл не будет работать...

Затем вам нужно начать изменять данные: это означает, что вам нужно пройти через "скрытые данные", извлекая их по биту за раз и заменяя наименее значимый бит каждого значения цвета скрытым. Когда вы закончите, скопируйте оставшуюся часть файла в выходной файл.

- Я? Я читал кусками, в идеале используя размер куска в восемь раз больше, чем количество байтов "скрытых данных". Таким образом, вы обрабатываете все данные в одном фрагменте массива и можете читать и записывать их все с помощью одной инструкции. Остальная часть файла - это просто цикл чтения-записи, пока у вас не закончатся данные.

Попробуйте: это довольно простая штука!