目前正在从事隐写术项目,在该项目中,给定消息(以字节为单位)和每个字节要修改的位数,将消息隐藏在任意字节数组中。
在结果消息的第一个解码字节中,该值的第一个(最左边)位设置为“1”而不是“0”。例如,当使用消息时"Foo".getBytes()
,maxBits = 1
结果是“Æoo”,而不是“Foo”(0b01000110 变为 0b11000110)。消息"Æoo".getBytes()
和maxBits = 1
结果是“Æoo”,这意味着据我所知,该位没有被翻转。
只有某些maxBits
消息字节的某些值会导致此错误,例如"Foo"
在maxBits
等于 1、5 和 6 时"Test"
遇到此问题,而在maxBits
等于 1、3 和 5 时遇到此问题。只有生成的第一个字符以它的结尾第一位设置,并且此问题仅发生在this.maxBits
与初始数据相关的指定值处。
- 为什么对于 的某些值
maxBits
,得到的解码消息的第一位总是 1? - 为什么不同的输入有不同的值
maxBits
可以正常工作,而其他输入则没有? maxBits
与原始数据相关的值和产生的错误结果的模式是什么?
编码和解码方法:
public byte[] encodeMessage(byte[] data, byte[] message) {
byte[] encoded = data;
boolean[] messageBits = byteArrToBoolArr(message);
int index = 0;
for (int x = 0; x < messageBits.length; x++) {
encoded[index] = messageBits[x] ? setBit(encoded[index], x % this.maxBits) : unsetBit(encoded[index], x % this.maxBits);
if (x % this.maxBits == 0 && x != 0)
index++;
}
return encoded;
}
public byte[] decodeMessage(byte[] data) {
boolean[] messageBits = new boolean[data.length * this.maxBits];
int index = 0;
for (int x = 0; x < messageBits.length; x++) {
messageBits[x] = getBit(data[index], x % this.maxBits);
if (x % this.maxBits == 0 && x != 0)
index++;
}
return boolArrToByteArr(messageBits);
}
取消设置、设置和获取方法:
public byte unsetBit(byte data, int pos) {
return (byte) (data & ~((1 << pos)));
}
public byte setBit(byte data, int pos) {
return (byte) (data | ((1 << pos)));
}
public boolean getBit(byte data, int pos) {
return ((data >>> pos) & 0x01) == 1;
}
转换方法:
public boolean[] byteArrToBoolArr(byte[] b) {
boolean bool[] = new boolean[b.length * 8];
for (int x = 0; x < bool.length; x++) {
bool[x] = false;
if ((b[x / 8] & (1 << (7 - (x % 8)))) > 0)
bool[x] = true;
}
return bool;
}
public byte[] boolArrToByteArr(boolean[] bool) {
byte[] b = new byte[bool.length / 8];
for (int x = 0; x < b.length; x++) {
for (int y = 0; y < 8; y++) {
if (bool[x * 8 + y]) {
b[x] |= (128 >>> y);
}
}
}
return b;
}
示例代码和输出:
test("Foo", 1);//Æoo
test("Foo", 2);//Foo
test("Foo", 3);//Foo
test("Foo", 4);//Foo
test("Foo", 5);//Æoo
test("Foo", 6);//Æoo
test("Foo", 7);//Foo
test("Foo", 8);//Foo
test("Test", 1);//Ôest
test("Test", 2);//Test
test("Test", 3);//Ôest
test("Test", 4);//Test
test("Test", 5);//Ôest
test("Test", 6);//Test
test("Test", 7);//Test
test("Test", 8);//Test
private static void test(String s, int x) {
BinaryModifier bm = null;
try {
bm = new BinaryModifier(x);//Takes maxBits as constructor param
} catch (BinaryException e) {
e.printStackTrace();
}
System.out.println(new String(bm.decodeMessage(bm.encodeMessage(new byte[1024], s.getBytes()))));
return;
}