【发布时间】:2016-02-19 03:55:37
【问题描述】:
目前正在从事一个隐写术项目,在该项目中,给定一条消息(以字节为单位)和每个字节要修改的位数,将消息隐藏在任意字节数组中。
在结果消息的第一个解码字节中,该值的第一个(最左边)位设置为“1”而不是“0”。例如,当使用消息"Foo".getBytes() 和maxBits = 1 时,结果是“Æoo”,而不是“Foo”(0b01000110 变为 0b11000110)。使用消息"Æoo".getBytes() 和maxBits = 1 结果是“Æoo”,这意味着据我所知该位没有被翻转。
只有某些消息字节的maxBits 的某些值会导致此错误,例如"Foo" 在等于1、5 和6 的maxBits 处遇到此问题,而"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;
}
【问题讨论】:
标签: java binary bit-manipulation byte off-by-one