PPM Görüntü üzerinde temel Steganografi yapmaya çalışıyorum.C Steranografi C
Temel algoritma tamamlandı. Dosyayı okuyun, başlığın P6 ile başladığını kontrol edin, görüntü genişliğini ve yüksekliğini ve piksel verilerini alın.
Toplam dört yönteme ihtiyacım var: ReadPPM, WritePPM, WriteMsg and ReadMsg.
ReadImg ve WriteImg yöntemleri aşağıdayım, ancak sıkıştığım yerde WriteMsg yöntemim var. Bu, her bir dizgenin her bir bitini her bayttaki son bit'e yazan temel steganografidir. İlk 8 bayt, gizlenen dizginin boyutunu, sonra da gizli iletiyi başlatan her baytın boyutunu içerecek şekilde varsayalım.
Fikrim, dizenin boyutuna ilişkin ikili kodu ve daha sonra dizenin kendisinin ikili kodunu tutan çok büyük bir dizi oluşturmaktı. Sadece bu diziyi nasıl alacağımı ve görüntüdeki her bayta nasıl eklediğimi anlamaya çalışıyorum.
Herhangi bir yardım çok takdir edilmektedir. İşte benim geçerli kod:
#include<stdio.h>
#include<stdlib.h>
typedef struct {
unsigned char red,green,blue;
} PPMPixel;
typedef struct {
int x, y;
PPMPixel *data;
} PPMImage;
#define CREATOR "RPFELGUEIRAS"
#define RGB_COMPONENT_COLOR 255
static PPMImage *readPPM(const char *filename)
{
char buff[16];
PPMImage *img;
FILE *fp;
int c, rgb_comp_color;
//open PPM file for reading
fp = fopen(filename, "rb");
if (!fp) {
fprintf(stderr, "Unable to open file '%s'\n", filename);
exit(1);
}
//read image format
if (!fgets(buff, sizeof(buff), fp)) {
perror(filename);
exit(1);
}
//check the image format
if (buff[0] != 'P' || buff[1] != '6') {
fprintf(stderr, "Invalid image format (must be 'P6')\n");
exit(1);
}
//alloc memory form image
img = (PPMImage *)malloc(sizeof(PPMImage));
if (!img) {
fprintf(stderr, "Unable to allocate memory\n");
exit(1);
}
//check for comments
c = getc(fp);
while (c == '#') {
while (getc(fp) != '\n') ;
c = getc(fp);
}
ungetc(c, fp);
//read image size information
if (fscanf(fp, "%d %d", &img->x, &img->y) != 2) {
fprintf(stderr, "Invalid image size (error loading '%s')\n", filename);
exit(1);
}
//read rgb component
if (fscanf(fp, "%d", &rgb_comp_color) != 1) {
fprintf(stderr, "Invalid rgb component (error loading '%s')\n", filename);
exit(1);
}
//check rgb component depth
if (rgb_comp_color!= RGB_COMPONENT_COLOR) {
fprintf(stderr, "'%s' does not have 8-bits components\n", filename);
exit(1);
}
while (fgetc(fp) != '\n') ;
//memory allocation for pixel data
img->data = (PPMPixel*)malloc(img->x * img->y * sizeof(PPMPixel));
if (!img) {
fprintf(stderr, "Unable to allocate memory\n");
exit(1);
}
//read pixel data from file
if (fread(img->data, 3 * img->x, img->y, fp) != img->y) {
fprintf(stderr, "Error loading image '%s'\n", filename);
exit(1);
}
fclose(fp);
return img;
}
void writePPM(const char *filename, PPMImage *img)
{
FILE *fp;
//open file for output
fp = fopen(filename, "wb");
if (!fp) {
fprintf(stderr, "Unable to open file '%s'\n", filename);
exit(1);
}
//write the header file
//image format
fprintf(fp, "P6\n");
//comments
fprintf(fp, "# Created by %s\n",CREATOR);
//image size
fprintf(fp, "%d %d\n",img->x,img->y);
// rgb component depth
fprintf(fp, "%d\n",RGB_COMPONENT_COLOR);
// pixel data
fwrite(img->data, 3 * img->x, img->y, fp);
fclose(fp);
}
void writeMsg(PPMImage *img, char *s)
{
int i;
int len;
len = sizeof(s);
if (img)
{
j = 0;
for (i=0; i < img->x * img->y; i++)
{
while(j < 8)
{
if(len & 0x80)
{
img->data[i].red= img->data[i].red | 0x01;
}
else
{
img->data[i].red= img->data[i].red & 0xFE;
}
len=len << 1;
j++;
if (len & 0x80)
{
img->data[i].green= img->data[i].green | 0x01;
}
else
{
img->data[i].green= img->data[i].green & 0xFE;
}
len = len << 1;
j++;
if (len & 0x80)
{
img->data[i].blue= img->data[i].blue | 0x01;
}
else
{
img->data[i].blue= img->data[i].blue & 0xFE;
}
j++;
}
}
}
}
Kodunuzun biçimlendirilmesi gerçekten çok iyi ... aslında yardım istediğiniz işlevler hariç! Lütfen düzeltin. Tamamen okunamaz durumda. – MatthewD
İki döngüye ihtiyacınız vardır: Biri ve diğeri, her karakterin biti ile, veriyi yalnızca ikinci döngü içinde yazıp @Patashu gibi veya ters sırada yazınız ('bayt << i & 0x80'). Uzunluk değişkeni dönme! –
'len = sizeof (s)' bir imlecin boyutunu döndürür. Dizenin uzunluğunu istiyorsanız, strlen() 'işlevini kullanın. – MatthewD