gpt4 book ai didi

java - 隐写术程序给出奇怪的结果

转载 作者:行者123 更新时间:2023-11-30 09:47:43 25 4
gpt4 key购买 nike

我正在为计算机编程类(class)开发隐写术程序。它似乎给出了随机的 ascii 符号。输出应该是二进制的。 encode message 方法是我老师给我们的。我们只需要对解码部分进行编程。

import java.awt.*;
class HideMessage {
public void encodeMessage(Picture stegoObject, int[] binaryArray) {
Pixel pixelTarget = new Pixel(stegoObject, 0, 0);
Pixel[] pixelArray = stegoObject.getPixels();
Color pixelColor = null;
int redValue = 0;

for (int x = 0; x < binaryArray.length; x++) {
redValue = binaryArray[x];
pixelTarget = pixelArray[x];
pixelTarget.setRed(redValue);
}
pixelTarget = pixelArray[binaryArray.length];
pixelTarget.setRed(255);
System.out.println("FinishedPic");
stegoObject.write("SecretMessage.bmp");
stegoObject.explore();

}
public void decodeMessage(Picture decodepic) {

int redValue = 0;
Pixel targetPixel = null;
Color pixelColor = null;
int sum = 0;

for (int x = 0; redValue < 2; x++) {
//inside nested loop to traverse the image from left to right
for (int count = 1; count < 9; count++) {

targetPixel =
decodepic.getPixel(count + (8 * x), 0);
//gets the x,y coordinate of the target pixel
pixelColor = targetPixel.getColor();
//gets the color of the target pixel

redValue = pixelColor.getRed();

if (redValue == 1) {
if (count == 1) {
sum = sum + 128;
}
if (count == 2) {
sum = sum + 64;
}
if (count == 3) {
sum = sum + 32;
}
if (count == 4) {
sum = sum + 16;
}
if (count == 5) {
sum = sum + 8;
}
if (count == 6) {
sum = sum + 4;
}
if (count == 7) {
sum = sum + 2;
}
if (count == 8) {
sum = sum + 1;
}
}

System.out.println(sum);

}
System.out.println((char)sum);
sum = 0;
} //end of the inner for loop
}
}

public class HideMessageTester {
public static void main(String[] args) {
int[] bitArray =
{ 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1,
0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0,
1, 1, 1, 1, 0, 0, 1 };
//int[] bitArray =
{ 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1,
0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1,
1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0,
0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1,
0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0,
0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1,
0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1,
0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0,
0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1,
0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1,
1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0,
0, 1, 0, 0, 0, 0, 1};

Picture stegoObject = new Picture("Earth.bmp");

HideMessage stego = new HideMessage();

stego.encodeMessage(stegoObject, bitArray);
Picture decodeObject = new Picture("SecretMessage.bmp");
System.out.println("Now Decoding");
stego.decodeMessage(decodeObject);
}
}

最佳答案

首先,一些一般性建议:我认为您的程序过于复杂,因为这些功能混合了它们的职责:

Picture stegoObject = new Picture("Earth.bmp");
HideMessage stego = new HideMessage();
stego.encodeMessage(stegoObject, bitArray);
Picture decodeObject = new Picture("SecretMessage.bmp");
System.out.println("Now Decoding");
stego.decodeMessage(decodeObject);

看到 SecretMessage.bmp非常很惊讶;试图解码您刚刚创建的对象一点也不明显。当然,在阅读 encodeMessage() 后方法很容易确定它来自哪里,但我认为这个流程会更容易:

/* encode */
Picture pic_to_steg = new Picture("foo.bmp");
HideMessage stego = new HideMessage();
Picture secret = stego.encodeMessage(pic_to_steg, bitArray);
secret.write("SecretMessage.bmp");

/* decode */
Picture pic_with_message = new Picture("SecretMessage.bmp");
int[] hidden = stego.decodeMessage(pic_with_message);

/* output `hidden` and compare against `bitArray` */

换句话说:将文件 IO 完全留给程序的主流程。也许将来您的例程将从网络服务器调用,而图片将永远不会保存到磁盘。如果例程在 Picture 上运行,那么修改会容易得多s 和 return 修正 Picture s 和 int[] .

你能测试一下你的encodeMessage()吗?孤立的方法?也许看看它在输入文件和输出文件之间所做的差异。这一段看起来很麻烦:

public void encodeMessage(Picture stegoObject, int[] binaryArray) {
Pixel pixelTarget = new Pixel(stegoObject, 0, 0);
Pixel[] pixelArray = stegoObject.getPixels();
Color pixelColor = null;
int redValue = 0;

for (int x = 0; x < binaryArray.length; x++) {
redValue = binaryArray[x];
pixelTarget = pixelArray[x];
pixelTarget.setRed(redValue);
}
pixelTarget = pixelArray[binaryArray.length];
pixelTarget.setRed(255);

pixelArray真的是可以通过简单赋值更新的图像引用吗?我真的希望设计看起来更像这个伪代码:

pixel p = image.getPixel(x, y);
p.setred(binaryArray[i]);
image.setPixel(x, y, p);

解码有一些奇怪的循环:

    for (int x = 0; redValue < 2; x++) {
//inside nested loop to traverse the image from left to right
for (int count = 1; count < 9; count++) {

这个循环可能完全按照您设计的那样工作,但初读时,感觉非常错误:您从 x=0 开始,你递增 x每次循环,但你使用 redValue < 2作为你的循环终止规则。

我非常希望看到这样的循环:

int x = 0;
while (redValue < 2) {
/* stuff */
x++;
}

(它不完全相同;x 在循环外仍然有效,这可能很危险。但是,我认为这更清楚。)

在某些情况下,for 的终止条款loop 与 setup 或 increment 子句无关——根据我的经验,它们非常很少见。

但在这种情况下,感觉像是一个错误;条件redValue < 2一个循环不变量,但内部循环假设它只会发生在 8 的倍数的像素上,这是一个在 encodeMessage() 中没有强制执行的假设方法。

试图从您的 redValue 计算一个整数值当您阅读它们时,它会不必要地使您的解码程序复杂化。我建议删除内部循环并返回一个与传入 encodeMessage() 的数组完全相同的数组常规。这将 (a) 更容易 (b) 更容易调试 (c) 更容易测试 (d) 处理不能被 8 整除的位数组要容易一千倍。

然后编写一个第二个方法,将位数组输出转换为总和、ASCII 字符、EBCDIC 字符、RSA key 参数,或任何正在编码的内容。不要试图一次做太多。编写一个单独的方法来解码位数组将 (a) 更容易 (b) 更容易调试 (c) 更容易测试 (d) 处理任意输出修改更容易一千倍。

我希望这些提示有所帮助。

关于java - 隐写术程序给出奇怪的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6541756/

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