惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

WordPress大学
WordPress大学
Cyberwarzone
Cyberwarzone
The GitHub Blog
The GitHub Blog
云风的 BLOG
云风的 BLOG
P
Proofpoint News Feed
小众软件
小众软件
Recent Announcements
Recent Announcements
博客园 - 三生石上(FineUI控件)
Security Archives - TechRepublic
Security Archives - TechRepublic
W
WeLiveSecurity
Cloudbric
Cloudbric
博客园 - 司徒正美
美团技术团队
N
News and Events Feed by Topic
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
PCI Perspectives
PCI Perspectives
宝玉的分享
宝玉的分享
H
Help Net Security
H
Hackread – Cybersecurity News, Data Breaches, AI and More
Google DeepMind News
Google DeepMind News
Help Net Security
Help Net Security
Last Week in AI
Last Week in AI
S
Schneier on Security
N
News | PayPal Newsroom
B
Blog RSS Feed
L
LINUX DO - 最新话题
T
Troy Hunt's Blog
S
Secure Thoughts
雷峰网
雷峰网
aimingoo的专栏
aimingoo的专栏
L
Lohrmann on Cybersecurity
G
Google Developers Blog
Microsoft Azure Blog
Microsoft Azure Blog
Hacker News - Newest:
Hacker News - Newest: "LLM"
T
Tenable Blog
S
Securelist
L
LangChain Blog
Recent Commits to openclaw:main
Recent Commits to openclaw:main
I
InfoQ
H
Heimdal Security Blog
Cisco Talos Blog
Cisco Talos Blog
F
Full Disclosure
Y
Y Combinator Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
K
Kaspersky official blog
T
Tailwind CSS Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
阮一峰的网络日志
阮一峰的网络日志
C
Cisco Blogs

ZDDHUB

PixelsMeasure 开发第二年总结 PixelsMeasure 开发一年总结 Swift/SwiftUI 踩坑记 为什么说 GPT 利好程序员 ChatGPT 编程实现 Web 数字水印 Micro Frontends for Mobile URL 加载系统(URL Loading System) Protocol Buffers GraphQL 从 0 到 1 开发一款 IOS 应用 - Swift MV* 软件设计架构 学习一个新技巧需要多久? 不停机数据库迁移 Rspec 如何 mock update 方法更新自己? Rails 使用 mysql2 出现的段错误 使用 Docker-compose 部署 Rails 应用到生产环境 Cocoa troubleshooting 独孤九剑 Dit (0x05) - 终端篇 Gem-based Jekyll theme 开发小记 Miscellaneous 前端手记 TodoMVC 之 Redux 篇 前端手记 TodoMVC 之 Server 篇 前端手记 TodoMVC 之 React 篇 前端手记 TodoMVC 之 CSS 篇 独孤九剑 Dit (0x04) - 测试篇 独孤九剑 Dit (0x03) - 缓存篇 英语小抄 LLDB debug Golang Make mistakes 大牛俱乐部上线啦 独孤九剑 Dit (0x02) - 数据结构篇 独孤九剑 Dit (0x01) - 总决 独孤九剑 Dit (0x00) - 我为什么要做 Dit 零值强制类型转换的使用 终端颜色输出重定向 Go语法简略 - 正则表达式 Makefile Go语法简略 - Duck框架探索 Go语法简略 - 依赖注入 Go语法简略 - web应用框架 Go语法简略 - 反射 Go语法简略 - 面向对象 Go语法简略 - goroutine Go语法简略 - 方法和接口 Go语法简略 - 基础篇 大牛 轻松科研 未来这几年 为 Android Studio 创建图标 Shell Git Vim 金庸答百问 论拖延症 Flex, A fast scanner generator 有理想的人 从虚拟到现实 常用视频转接口 Recognizer configuration on CentOS 整个世界清静了 《Python源码剖析》读书笔记
Web 数字水印探究
zddhub · 2023-03-16 · via ZDDHUB

文心一言发布后,除了训练数据规模、训练结果和 ChatGPT 有差异外,界面上还多了水印。这篇文章主要探究文心一言使用的 Web 数字水印技术。

那什么是 Web 水印呢?GPT-4 帮我写了个带文心一言同款水印的网页,感兴趣的同学可以来这里感受一下。

如果你一看就懂或者能去掉上面网页里的水印,那这篇文章你是不用读的。

缘起

半年来,ChatGPT 3.5 彻底颠覆了人们对语言模型技术的认识,一时风光无两,瞬间碾压了 Web3、区块链和元宇宙。2023 年 3 月 14 日 ChatGPT 4.0 重磅发布,进化速度之快令人乍舌。百度也不甘寂寞,两天后发布了自家研发的知识增强大语言模型——文心一言。发布会上录屏演示,略显不自信,一时间股票暴跌 10%。原以为邀请码会遥遥无期,结果当天晚上就收到了短信,拿到了体验号。今天的故事就从这里开始。

体验了一番文心一言后发现,发布会上说的除了生成视频之外,基本可用。通过比较,效果和模型距 ChatGPT 还有很大差距,请飞速进化。其中,作画功能很有趣,让人忍不住有分享的冲动。比如下面这幅:

ERNIE-Bot-draw-image

刚要发朋友圈分享一下,突然发现背景模模糊糊的。凑近一看,一串代码,盲猜是邀请码。才反应过来,这是水印啊!一个体验的产品,要什么水印!要用来干什么?这是在防谁?(此处省略腹黑脑补一万字……)

分享一个带水印的图片,总觉得不安心。管它呢,删掉就可以了,这能难得到我!

文心一言界面水印去除

立马打开了 Console。

呵呵,嘴角微微上扬,这原来只是一段 DOM。

<div id="eb-watermark" style="pointer-events: none !important; display: block !important">
    #shadow-root(open)
    <div id="mask_div_id00" style="display: block; ...">KFCVW50</div>
    ...
    <div id="mask_div_id100" style="display: block; ...">KFCVW50</div>
</div>

意外的是,它并不像我想的那么容易删除。以下是一些失败的尝试:

  1. 删除 DIV 之后,又被加了回来。
  2. 设置 display: none !important; 或者 visibility: hidden !important; 后, 又被加了回来。
  3. 设置 width: 0; height: 0; 后,又被加了回来。
  4. 编辑属性,或者编辑 HTML 后,又被加了回来。

这些尝试已经耗尽了我所有的前端知识储备。

又经过一番尝试,最后发现:DOM 删除和修改都不行,但是 innerText 是可以替换的。那么,去除文心一言水印的方法就来了:

打开 Console 运行:

// Before 2023-03-31
document.getElementById("eb-watermark").shadowRoot.childNodes.forEach(node => node.innerText = "")

(2023-03-21)再看时,id 已经更新被成了 eb_16793967784870.9188072908333647。更新一下代码就好:

document.querySelectorAll('[id^="eb_"]')[0].shadowRoot.childNodes.forEach( node => node.innerText  = "")

今天(2023-03-24)再看时,id 已经更新被成了 5a705805-5397-4e47-bf6d-e7af8c458976。这次用一个 CSS 就删掉了,大家先试一下。

只要不调整浏览器大小或者刷新,就能够保持住。这时,就可以安心地截图分享了。

这种水印是怎么做的?

我是老网民了,有空也会上网,是见过水印的。知道图片、文档在二进制中暗藏水印。但像这种 Web 上的水印还是头一次见,或者说是头一次吸引了我的注意。

那它到底是怎么实现的呢?HTML 没有魔法,要有,那一定是 JavaScript 干的。在 DOM 修改或删除后,又被重新添加了。那么是如何监听 DOM 修改和删除的呢?

常言道,外事不决问谷歌,内事不决问百度。人工智能时代,万事都问 ChatGPT。

问:如何监听 dom 的修改和删除

ChatGPT:要监听 DOM 的修改和删除,可以使用 JavaScript 中的 MutationObserver 对象。MutationObserver 是一个异步 API,用于监视 DOM 树中的变化。当监视的元素或子元素的属性发生变化、添加或删除时,MutationObserver 会接收到通知并触发回调函数。

以下是一个简单的示例,演示如何使用 MutationObserver 来监听 DOM 的修改和删除:

// 选取需要监听的元素
const targetNode = document.getElementById('target-element');

// 创建一个 MutationObserver 对象
const observer = new MutationObserver((mutationsList, observer) => {
  // 遍历所有变化
  for (const mutation of mutationsList) {
    if (mutation.type === 'childList') {
      // 监听子元素的添加或删除
      console.log('A child node has been added or removed.');
    } else if (mutation.type === 'attributes') {
      // 监听属性的修改
      console.log('The ' + mutation.attributeName + ' attribute was modified.');
    }
  }
});

// 配置观察选项
const config = { attributes: true, childList: true, subtree: true };

// 开始观察目标节点
observer.observe(targetNode, config);

哦,原来答案是 MutationObserver,监听到 DOM 变化后删除它,再添加一个新的,就能实现文心一言的水印效果了。

什么?你也想问文心一言这个问题?好的!

DOM-Observer 注:AI 随时在进化,这是文心一言发布当天的测试结果。

此时此刻,我想吟诗一首:

手持两把锟斤拷

口中疾呼烫烫烫

脚踏千朵屯屯屯

笑看万物锘锘锘

哎,希望进化的快一点吧。

堵住文心一言水印的漏洞

上面提到,修改 innerText 可以去掉文心一言的水印,那么 innerText 的修改能监听到吗?要是有个配置就好了,再问 ChatGPT:

问:Config 能配置监听 innerText 的修改和删除吗?

ChatGPT:是的,MutationObserver 的观察选项(config)可以配置监听 innerText 的修改和删除。具体来说,可以通过设置观察选项的 characterData 属性为 true 来仅监听文本内容的变化,而忽略元素节点的增加、删除、属性修改等其他变化。

设置观察选项的 characterData 属性为 true,表示仅监听节点的文本内容变化,而忽略其他类型的变化,如节点添加、删除、属性修改等。当目标节点的 innerText 属性发生变化时,MutationObserver 会调用回调函数,并将变化信息传递给它。

是的,可以通过设置 const config = { characterData: true, ...}; 来监听 innerText 的改变。

齐活儿,漏洞堵上了!

写在最后

人工智能时代,文心一言的水印和这篇文章也在不断进化,最新版本请移步我的博客

咦,怎么突然就从人工智能跳到水印了呢?不说了,我要赶紧去学习了,要不焦虑感就会一直留在我的心里,就像那无法去除的水印一样。

如果你喜欢这篇文章,欢迎赞赏作者以示鼓励