返回知识中心
指纹

CreepJS Emoji 度量:集合与总和能说明什么

沿固定版本源码解读 CreepJS 的 emojiSet 与 textMetricsSystemSum,区分代表集合、有损聚合和字段纳入条件,不把度量当作操作系统身份。

BotBrowser Team

文档中心

想直接进入 指纹 文档吗?

这篇文章属于知识中心的指南库。若你要步骤化配置、参考说明和持续更新,请直接进入对应 docs 分区。

CreepJS Emoji 度量描述文本几何,以及库如何将这些几何结果分组。emojiSet 和 textMetricsSystemSum 这样的名称,不会把测量结果变成操作系统身份证明。BotBrowser 文档说明了配置档字体与 Emoji 字体回退能力,但不承诺每个文本度量都完全相同,也不能通过 CreepJS 的汇总值确定操作系统。

相关依据是公开源码的固定版本 10aa6724cd33a1015db1574211890518cd04f0cc,核对日期为 2026-11-02。引用的 canvas 代码块选择代表并求和;引用的组装代码块决定保留哪些字段。这两个块都没有分配操作系统标签。这是源码解读,不是已经执行的浏览器对比,也不代表 CreepJS 其他位置不存在推断逻辑。

摘要

  • emojiSet 为每组不同的七字段文本度量元组保留首个遇到的 Emoji,不是完整的 Emoji 支持清单。
  • textMetricsSystemSum 聚合的是唯一度量元组,不是给每个输入 Emoji 分别计权。汇总会丢失信息。
  • 结果组装针对像素字段检查 lied,针对度量字段另行检查 liedTextMetrics。解释缺失需要分支上下文。
  • 几何相等不等于像素相等、字体文件相同或操作系统相同。操作系统分类需要这些代码块之外的证据。
  • 比较汇总值前,先比对源码版本、度量字段组成和纳入阶段。不要把原始指纹材料写入日常支持日志。

目录

五个源码阶段:measureText 产生七项度量,pattern 保留不同元组,emojiSet 选择代表,textMetricsSystemSum 汇总唯一元组,liedTextMetrics 控制是否纳入结果。这些代码块没有分配操作系统标签。

七项度量描述几何

测量对象不是图像

固定版本的 CreepJS canvas 源码 调用 context.measureText(emoji),读取七项属性:actualBoundingBoxAscent、actualBoundingBoxDescent、actualBoundingBoxLeft、actualBoundingBoxRight、fontBoundingBoxAscent、fontBoundingBoxDescent 和 width。这些值被拼接成元组表示。去重键是这个元组,不是 Emoji 绘制后的图像。

MDN 的 measureText 参考 说明返回值是 TextMetrics 对象。TextMetrics 参考 区分文本前进宽度与边界框度量,并说明它们以 CSS 像素为单位。因此,仅 width 相同,比选中的七项属性全部相同更弱。这两类比较都不包含已渲染字形的逐个颜色或边缘像素。

两份报告都说 Emoji“匹配”时,这个区别很重要。一份可能指宽度相同,另一份指选中的元组相同,第三份则比较渲染图像。它们的输入与比较对象不同。文本度量指纹分析 将几何、栅格输出和字体加载状态分开。相等结论应该说明所属层,不能让图像结论直接继承度量结果。

字体匹配是另一项依赖

CSS Fonts 匹配规范 描述字体选择与回退。请求了某个字体族,不足以证明每个字符都来自同一个字体文件。因此,measureText() 得到的几何不是文件清单。canvas 设置里出现过字体族名称,也不能让元组对比恢复一个未被记录的字体选择路径。

Unicode Emoji 规范 区分文本呈现请求与 Emoji 呈现请求。呈现与回退是相关上下文,但选中的 TextMetrics 属性仍是最终文本布局的度量。支持记录不应该用看起来相似的截图替换真实输入序列:视觉相似无法保留原始的呈现请求。

代表集合不是支持清单

选择依据是元组,不是支持判定

在 src/canvas/index.ts:369-394,CreepJS 维护 pattern 集合。只有尺寸元组尚未出现在集合中,Emoji 才进入 emojiSet。后续输入如果产生已有元组,就不增加代表。因此,没有出现在 emojiSet 中的输入仍可能已经成功测量;该分支不要求出现“不支持字形”的判定。

一个假设分组可以说明后果。假设两个不同输入字符串产生同一组选定几何,另一个输入产生不同元组。代表集合保留第一组的一个成员,以及第二组的一个成员。这既不说明被舍弃成员不可用,也不说明两个保留成员识别出了两个字体文件。分组规则只涉及选定属性是否相等。

顺序也有有限但重要的作用。emojiSet 接收每个新模式中首个遇到的成员,因此,即使唯一元组集合不变,改变输入顺序也可能改变代表。代表列表不同,不足以证明环境发生变化。应先确认源码版本与输入序列可比。

从源码到结论的边界表

下表用于解释源码,不是浏览器输出。每行说明该阶段最多支持什么结论。后续分类器使用了某阶段的数据,不代表分类过程就属于那个阶段。

阶段源码操作产生对象支持的解释不支持的捷径
测量读取七项 TextMetrics 属性几何元组选定的文本几何操作系统身份
去重将新元组加入 pattern不同模式选定度量存在差别不同字体文件
代表选择保留每个模式的首个成员emojiSet度量分组的代表完整 Emoji 支持情况
聚合汇总唯一元组textMetricsSystemSum有损度量摘要可逆的设备身份
结果组装分别检查 liedTextMetrics被纳入的度量字段这份源码的纳入决定外部服务的判定

这个判断规则可以纠正常见报告错误:不能将 emojiSet 的成员数当成已安装字体数,也不能将缺席成员当成失败字形。如果问题是用户的消息无法阅读,度量组数并不能回答目标序列是否正确显示。应该在获授权的应用里检查用户可见的渲染问题,而不是把指纹字段当作字形支持测试。

求和会丢失被汇总的结构

唯一分组,不是频次权重

src/canvas/index.ts:396-399 的聚合遍历 pattern,也就是唯一元组表示的集合。重复输入如果得到已有元组,不会在此阶段再贡献一份。因此,总和不衡量输入集合使用某种几何的频率。假设每个原始输入都等量参与计算,描述的是另一个算法。

转换与归约还会压缩其他区别。公开实现将元组分量转成数字,并在数值转换结果为假值时以零替代,然后相加。出现了汇总结果,不等于每个被选属性都存在、非零且有限。原始属性是否可用,与数值汇总是两回事;后者无法恢复前者。

求和会丢失分量排列。不同元组可以得到同样总和,不同元组集合也可能共享聚合值。这是加法丢失信息的推论,不是观察到的碰撞率,也不是测量过的浏览器人群。总和存在,并不能导出唯一性百分比、识别置信度或操作系统分类准确率。

像素生成走另一条路径

canvas 模块也生成渲染数据,但 textMetricsSystemSum 不是 Emoji 图像所有像素的摘要。度量比较与像素比较应该保留不同的结果名。报告如果都写成“canvas 匹配”,即使原始收集程序保留过区别,也无法从这句话分辨布局相等还是栅格相等。

CreepJS canvas 种子分析 讨论确定性绘制请求与渲染输出的关系。它不能替代度量分组问题:知道绘制序列,不等于知道哪些文本元组会合并。反过来,代表几何相同,也不等于绘制请求、图像输出或后续聚合流程相同。

在获授权的兼容性对比中,应保留真正的问题。意外换行涉及 width 与布局上下文;Emoji 无法阅读涉及可见字形。聚合值可以指出报告不同,却不解释这两种用户故障。把故障替换为指纹分数,会丢掉修复应用需要的证据。

像素字段和度量字段分别纳入

纳入逻辑不是 canvas 的总开关

固定版本的结果组装源码 先检查传入的 canvas2d 模块结果;没有结果就直接返回。模块结果存在时,分别处理两个条件。!lied 分支纳入 dataURI、paintURI、textURI 和 emojiURI;!liedTextMetrics 分支纳入 textMetricsSystemSum 和 emojiSet。

这里必须保留 JavaScript 取反的语义:!lied 和 !liedTextMetrics 都允许任何假值,不要求一定是字面布尔值 false。源码说明的是纳入条件,不能把标记缺失翻译为已经完成验证。同样,lied 与 liedTextMetrics 是库的标识符,不是关于一个人是否诚实、意图如何的结论。

第二个分支会保留第一个分支已组装的数据;前面的数据不存在时,就创建新对象。因此,即使像素分支没有填充字段,度量字段也可能被纳入。导出程序如果将这些情况合并成一个“canvas 被拒绝”标签,就抹掉了引用源码里本来存在的区别。

缺失字段需要周边记录

现有证据有边界的解释仍缺少什么
没有传入的 canvas2d 结果此组装块没有该模块结果就返回模块结果为何缺失
像素分支未纳入,度量分支纳入两组数据独立处理任何操作系统分类或像素对比
模块结果存在,但度量条件不允许字段进入度量纳入在这一阶段被阻止后续导出是否还转换过数据
下载报告没有 emojiSet检查到的报告里没有可见字段模块结果、纳入分支与导出历史

这些是基于源码的情况,不是已复现的运行。尤其是,下载报告中没有 emojiSet,不能在缺少模块结果和分支状态时直接选择第三行。导出过滤、结构变化和模块结果不可用,仍是不同可能。观察属于哪一层,就记录哪一层,不能从最终空字段推断之前发生了什么。

报告比较需要数据来历

源码版本属于比较条件

在字段名旁记录固定的 CreepJS 版本。10aa6724cd33a1015db1574211890518cd04f0cc 标识这里读取的源码;指向移动分支的 URL,不能证明另一份报告使用了同样的元组字段和结果组装器。只有日期,也无法证明当时页面提供了哪些源码字节。即使两份导出使用同样标签,这个限制仍然存在。

观察阶段应与版本一同记录。canvas 模块对象、组装后的指纹对象和下载报告,不一定暴露同样字段。解释缺失的 textMetricsSystemSum 前,应确认支持附件包含哪种对象,以及是否经过删除或重命名字段的转换。如果来历未被保留,就将原因记为未确定,而不是补出一段执行历史。

对于获许可的已有记录对比,下表定义最小的数据来历说明。这些是建议的支持字段,不是 CreepJS 导出格式,也不是 BotBrowser 自动产生的记录。只保留支持目的需要的内容;指向用户自主管理附件的引用,可能比将原始度量向量复制进日常分析更合适。

支持字段回答的问题采集边界
源码版本正在解释哪份实现固定真实版本,不假定当前分支
对象阶段模块、组装对象还是导出记录不推断未观察的早期状态
度量组成是否选择同样七项属性先记录结构,再考虑原始值
代表语义是否为唯一元组的首个成员不将代表重命名为字体支持
用户可见症状换行、缺字,还是只有报告变化将应用问题与身份判断分开

操作系统标签需要自己的证据

这两个引用代码块都不包含缺失的分类步骤。报告如果增加了操作系统标签,需要单独说明规则、输入和验证依据。在标签旁看到 textMetricsSystemSum,不证明总和唯一决定了标签;后续组件显示的标签,也不是 measureText() 文档给出的结论。

人群层面的判断又需要另一类证据。源码检查不能建立某个值在真实用户中的出现频率,也不能说明浏览器版本是否改变分布。这里没有开展浏览器人群研究。变量名里的非正式用词“system”,不能被转成实测识别准确率、跨设备稳定性,或不同安装绝不共享同一数值的保证。

BotBrowser 字体控制的承诺更窄

BotBrowser 字体文档 说明配置档字体清单、跨平台字体渲染,以及与平台相应的 Emoji 回退。这些是产品能力,不是 CreepJS 仓库、MDN 或 Unicode 提供的主张。同一份 BotBrowser 文档也明确允许部分布局度量存在差异;配置档设置不保证每个字形或文本度量属性都得到完全相同的结果。

获授权的应用可以使用声明过的配置档,检查具体布局或渲染要求。验收问题应指向要求本身:目标消息是否仍可阅读,已知文本是否按设计换行。不能用“CreepJS 推断出了目标操作系统”替代应用正确性,也不能仅凭 emojiSet 匹配,就推断配置档已成功加载。

文档页与源码解读回答不同问题。文档说明配置能力及其边界;上面的矩阵说明一个公开实现如何归约度量并决定字段纳入。区分两者,可以避免把产品控制描述变成对外部分类器结果的承诺,也避免把外部收集程序的字段名称说成 BotBrowser 文档规定的输出。

常见问题

emojiSet 较短是否代表支持的 Emoji 更少?

不是。引用代码依据新度量元组进行选择。多个能够测量的输入可能共享一个元组,只在 emojiSet 中留下首个代表。支持清单需要另一种测试以及关于目标字形的证据,代表数量不能提供这种结论。

总和相等能否确定操作系统相同?

不能。textMetricsSystemSum 压缩唯一元组并丢失排列。两个引用代码块不分配操作系统标签,这里也没有声称做过浏览器人群验证。后续分类器需要自己的证据;聚合值相等不能认证操作系统、物理设备或个人。

为什么像素字段缺失时度量还能保留?

组装器分别检查 lied 与 liedTextMetrics。即使像素分支没有提供对象,度量分支仍能创建对象。这个源码路径说明一种可能的字段组合;缺少周边模块与导出证据时,不能据此确定具体下载报告经过了哪个路径。

资料来源

实践结论

将 emojiSet 理解为唯一几何的代表,将 textMetricsSystemSum 理解为有损摘要,再确认字段纳入阶段,才能解释缺失。获授权的对比应保留源码版本和对象来历。渲染故障需要应用的直接证据,操作系统标签需要另行成立的依据;这些代码块既不是支持清单,也不提供设备身份。

#CreepJS#Emoji Metrics#Font Fingerprinting#Canvas#隐私

本文属于指南: 什么是浏览器指纹?原理、风险、信号与隐私边界

让 BotBrowser 从研究走向生产

先用这些指南理解模型,再进入跨平台验证、隔离上下文和面向规模化的浏览器部署。