为何PIL的Image.fromarray()会修改数组?LSB隐写保存后消息丢失
LSB隐写保存JPG后消息丢失问题
我通过修改像素RGB值的最低有效位(LSB)在图片中隐藏消息,不保存图片时直接遍历RGB数组能正常读取消息;但执行以下代码保存图片后,数组被修改,完全无法读取隐藏消息。
保存图片的代码:
res_img = Image.fromarray(im) res_img.save("freshly_hidden_message.jpg")
隐藏消息的代码片段:
for index, bit in enumerate(hidden_message_bits): val = im[index] val = bin(val) val = val[:-1] + bit im[index] = int(val, 2)
读取消息的代码片段:
while msg[-5:] != "^END^": bits = [bin(i)[-1] for i in im[index:index + 8]] print(bits) bits = "".join(bits) msg += chr(int(bits, 2)) index += 8 print("Hidden message is:",msg[:-5])
未保存时能正确读取消息“Testing”,保存后的输出为乱码。
问题根源
JPG是有损压缩格式,保存时会通过压缩算法丢弃视觉上不重要的像素信息——你修改的LSB刚好属于这类“无足轻重”的比特位,会被压缩过程直接篡改或清除,导致隐藏的消息比特完全丢失。
解决办法
- 改用无损图片格式保存:将保存格式换成PNG、BMP这类无损格式,示例代码:
这类格式会完整保留像素原始数值,LSB中的隐藏信息不会被破坏。res_img.save("freshly_hidden_message.png") - 若必须使用JPG:可以尝试修改像素值的第2或第3位(而非最低位),但这会轻微影响图片视觉效果,且依然存在被压缩算法干扰的风险,可靠性远不如无损格式。
内容的提问来源于stack exchange,提问作者GrozniV
相关产品推荐
相关产品推荐

