gpt4 book ai didi

c - C语言中的隐写术

转载 作者:太空狗 更新时间:2023-10-29 17:25:47 28 4
gpt4 key购买 nike

尝试对 PPM 图像进行基本的隐写术。

我已经完成了基本算法。读入文件,查看文件头是否以P6开头,获取图片的宽高和像素数据。

我一共需要四个方法:ReadPPM、WritePPM、WriteMsg和ReadMsg。

我有 ReadImg 和 WriteImg 方法,但我卡住的地方是我的 WriteMsg 方法。这是基本的隐写术,它只是将字符串的每一位写入每个字节的最后一位。前 8 个字节假定包含被隐藏字符串的大小,然后每个字节开始隐藏消息。

我的想法是创建一个大型数组,其中包含字符串大小的二进制代码,然后是字符串本身的二进制代码。我只是想弄清楚如何获取该数组并将其添加到图像中的每个字节。

非常感谢任何帮助。这是我当前的代码:

#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++;
}
}
}
}

最佳答案

要从一个字节中提取单个位,请执行以下操作:

bit(i) = byte >> i & 0x1

这会将字节的位向右移动 i 次,然后将其与 0000 0001 相加(这样除最低位外的所有位都归零,最低位为 0 为 0 和 1 1).

您可以对 16 位 short、32 位 int、64 位 long 执行类似的操作...甚至对于字符串的 char。您可以使用 sizeof(char) 查看一个 char 中有多少字节。

但是当然你会有不止一个字符(或 long 或 int 或...)来额外位。要决定从哪个元素中增加一点:

如果您想要第 i 位并且元素是 x 位宽,那么从元素 中获取 i%x 位[i/x]

现在你有了这个位,把它放在一个字节(或 int 或 char 或...)中,做:

隐写术字节 = originalbyte&(~0x1) + 位

这意味着,您取数字 ... 0000 0001,将其位取反,使其成为 ... 1111 1110, 将其与原始字节一起保留,因此保留其所有位 EXCEPT最低的,然后只需添加你的位。

关于c - C语言中的隐写术,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15651567/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com