一些社区为了防止内容被整页搬运、截图转载后无法确认来源,会在论坛界面中加入追溯信息。它最初的目的并不难理解:保护原创内容,发生搬运时能够知道截图从哪里流出。
一种最直观的做法,就是在页面中加入不容易注意到的标记。经过特定处理以后,截图上甚至可以直接显现出类似“工作留痕”的用户名水印,从而方便追溯截图来源。
站在防搬运的角度,这套逻辑本身很好理解。
问题在于,技术所处的社区环境会改变人们怎么看待它。
当一个社区越来越封闭,一些关于论坛本身的负面意见、争议帖可能遭遇屏蔽、删帖,甚至伴随着封号争议以后,原来用于“防止搬运”的追溯机制,在部分普通成员眼里就可能变成完全不同的东西:
我把自己亲眼看到的事情截图出去,会不会被找到?
于是本来只是想如实保存、转发一段公开讨论的人,也开始不敢截图。
甚至有人会在发图之前反复裁剪、重新保存、清除元数据,担心图片里面还有自己看不见的标记。
久而久之,大家讨论的已经不只是“怎么防搬运”,而是:
一张看起来完全正常的截图,到底还能携带多少我们肉眼看不到的信息?
于是我上知乎、问ChatGPT,大致了解技术细节,目前更有可能是 LSB 隐写技术。
太好笑了,这不正是大家口中这里论坛的缩写吗?lsb们哈哈哈!
先说清楚一点:
本文是技术讨论。出现像素差异,不等于某个论坛一定使用了 LSB 水印。
论坛实际采用什么追溯方案,需要通过样本对照、程序分析等方法验证,不能仅凭猜测下结论。
但 LSB 本身确实是一种非常有意思的隐写方法。
一张普通的 8 bit RGB 图片,每个像素都有三个颜色通道:
R:0 ~ 255
G:0 ~ 255
B:0 ~ 255比如某个红色通道的数值是:
255 = 11111111如果把它改成:
254 = 11111110数值只变化了 1。
肉眼看:
255
254基本没有任何区别。
但是计算机看到的是:
11111111
11111110最后一个二进制位已经发生了变化。
这个最后一位,就是:
LSB,Least Significant Bit,最低有效位。
于是就产生了一个很聪明的思路:
既然改变最低位几乎不会影响人看到的颜色,那么能不能用这些最低位来存东西?
当然可以。
假设连续读取若干像素的最低位:
0 1 0 0 1 0 0 0组合起来就是:
01001000按照 ASCII 解码:
H如果继续读取,就可以组成:
Hello理论上同样可以存:
user_id=123456也可以存时间、编号或者其他二进制数据。
这就是经典的:
LSB Steganography(最低有效位隐写)。
为什么肉眼看不出来?
例如原来的一个像素:
RGB(255, 180, 42)为了写入几个 bit,变成:
RGB(254, 181, 42)每个通道只是:
±1正常情况下,人眼几乎不可能察觉。
于是就出现了一件挺反直觉的事情:
两张图片看起来可以一模一样,但从数据角度看,它们并不是同一张图片。
清除 EXIF,并不等于清除隐藏信息
这是我分析以后觉得最值得提醒。
图片里面的信息大致可以分成不同层次。
第一层是大家比较熟悉的:
EXIF
XMP
PNG Text Chunk
ICC Profile
创建软件
创建时间
GPS
相机型号这些属于图片文件中的附加信息。
很多所谓:
清理图片元数据
处理的就是这一层。
但 LSB 完全不一样。
因为它直接修改:
Pixel RGB也就是图片本身的像素。
所以即便你把:
EXIF
XMP
备注
GPS
创建时间全部删掉,如果 RGB 像素一点没有变化,那么原本存在的 LSB 信息理论上仍然可以原封不动地留下。
所以:
清除元数据 ≠ 清除像素级隐写。
怎么观察一张图片的 LSB?
比较经典的方法叫:
Bit Plane Analysis(位平面分析)
一个 8 bit 色彩通道其实可以拆成八层:
bit 7
bit 6
bit 5
bit 4
bit 3
bit 2
bit 1
bit 0其中 bit 7 权重最大。
bit 0 就是最低有效位。
程序可以把整张图片的 bit 0 单独拿出来:
LSB = 0 → 黑
LSB = 1 → 白然后生成一张新的黑白图观察。

正常图片的最低位本身不是一张“干净的白纸”。
抗锯齿、图片处理、颜色计算、GPU 渲染、截图程序都会在里面留下大量变化。
所以:
看到 LSB 很乱,并不能证明存在隐写。
固定周期
规则点阵
特定位置反复变化
不同账号出现稳定差异
某一颜色通道异常
与图像本身明显无关的结构等等。
“不同账号截图对照”
如果真的怀疑某个平台加入了用户级追踪信息,与其盯着一张截图猜,不如做一个控制变量实验。
例如:
账号 A
账号 B分别访问完全相同的页面。
使用:
同一台电脑
同一个浏览器
同一个浏览器版本
同一个缩放比例
同一个窗口尺寸
同一块显示器
相同页面状态然后截图。
接下来做:
Pixel Diff(逐像素比较)
例如某个位置:
账号 A:
RGB(32, 32, 32)
账号 B:
RGB(33, 32, 32)另一个位置:
A:RGB(240, 240, 240)
B:RGB(240, 241, 240)单独看两张截图,人眼什么都发现不了。
但程序会马上看到:
+1
-1
+1如果这种差异:
- 大量存在;
- 总是在固定位置;
- 同一个账号重复截图结果稳定;
- 换账号以后模式发生稳定变化;
那就比“肉眼感觉有水印”有研究价值多了。
当然,即使发现这种现象,也不能立刻说:
找到用户水印了。
因为字体抗锯齿、GPU、动画、时间显示、头像加载、浏览器合成等,都可能产生差异。
所以最重要的是:
控制变量。
如果真的是传统 RGB-LSB,怎么破坏?
最简单的方法其实非常粗暴。
直接把 RGB 最低位全部归零:
R = R & 254
G = G & 254
B = B & 254例如:
255 → 254
254 → 254
253 → 252
252 → 252
129 → 128
128 → 128一个通道最大只变化:
1 / 255视觉影响通常极小。
但所有:
bit 0都会被覆盖。
如果原始信息确实通过 RGB 最低位编码:
0 1 1 0 1 0 0 1 ...处理以后可能直接变成:
0 0 0 0 0 0 0 0 ...原有 LSB 数据自然就被破坏了。
还可以使用另一种方法:
随机重写 bit 0。
例如:
255 → 254 或 255
183 → 182 或 183
42 → 42 或 43这样既可以破坏原来的最低位数据,也不会制造:
整张图片所有最低位全部为 0这种明显的人为统计特征。
现代数字水印完全可能不用 bit 0。
例如还可以在:
bit 1
bit 2
亮度
色度
纹理
DCT
DWT
频域
扩频信号
多尺度特征里面编码。
一些鲁棒数字水印甚至专门追求:
截图以后还在
JPEG 压缩以后还在
缩放以后还在
轻微裁剪以后还在
改变一点亮度以后还在这种水印,就不是简单:
RGB & 254能够解决的。
说到底,真正有意思的不是 LSB 本身,而是技术用途会随着环境发生变化。
一个追溯机制最初可能只是为了:
防搬运、保护原创。
这个出发点完全可以理解。
但如果一个社区逐渐让成员产生:
“我截图会不会被追踪?”
“我把公开内容转出去会不会被处罚?”
“这张 PNG 里面有没有我的账号信息?”这样的顾虑,那么问题就已经不只是“水印技术先进不先进”了。
技术本身没有情绪。
真正决定人们如何感受一项技术的,是它被放在什么样的规则、权力关系和社区信任环境里面。
一个成员彼此信任、规则透明、处罚边界清楚的社区,即使存在内容追溯机制,大家未必会紧张。
反过来,当成员开始担心正常讨论、正常截图、正常保存公开内容都会产生后果时,同样一项技术就很容易被理解成监视工具。
最后甚至会出现一种很荒诞的状态:
大家不是不敢说秘密,而是不敢截图公开发生过的事情。
真正靠谱的方法应该是:
拿样本
做实验
控制变量
逐像素比较
分析位平面
重复验证能证明什么,就说什么。不能证明的,就停在“未知”。
现在我做了测试,对 Mac Chrome LINUX DO论坛截图目前没发现隐藏水印。
但我对以下截图写入了隐藏水印技术,留给大家玩玩,当作是实验。
做出来了第一个给出答案并说清楚操作方法,奖励100积分。
说到这儿突然想起有点像本科实验哈哈哈,“理解并掌握原理”这句话我经常写实验报告,有时一周写五六个实验报告累得骂娘。
