最近看到word-wrap源码里面有一个正则,有点迷惑:
if (options.cut !== true) {
regexString += '([\\s\u200B]+|$)|[^\\s\u200B]+?([\\s\u200B]+|$)';
}
零宽空格
如果要搞清楚这句正则是干什么的,就需要了解到零宽空格了。
零宽空格(zero-width space, ZWSP)是一种不可打印的Unicode字符,用于可能需要换行处。 zh.wikipedia.org/wiki/%E9%9B…
复制这个om,作如下动作:
水印原理
零宽连字和零宽不连字
零宽连字(zero-width joiner,ZWJ)是一个控制字符,放在某些需要复杂排版语言(如阿拉伯语、印地语)的两个字符之间,使得这两个本不会发生连字的字符产生了连字效果。零宽连字符的Unicode码位是U+200D (HTML: )。 zh.wikipedia.org/wiki/%E9%9B…
具体例子可以看到wiki上的例子。
零宽不连字 (英文:zero-width non-joiner,缩写:ZWNJ)是一个不打印字符,放在电子文本的两个字符之间,抑制本来会发生的连字,而是以这两个字符原本的字形来绘制。Unicode中的零宽不连字字符映射为U+200C zero width non-joiner,HTML字符值引用为: zh.wikipedia.org/wiki/%E9%9B…
文本水印
我们常见的有图片水印,软件水印,视频水印等。那文本上的水印要是什么样子呢?
- 文本中间穿插文案,比如
这是一段[xxx.com]示例文案,说明这句话[xxx.com]的出处。 - 文本中通过某些不可见的字符,来携带水印。用户看不见,但是复制粘贴会携带上。
第一种就不说了,我们来看看第二种。上面说了两种领宽字符,恰好满足了不可见,且会被复制的特点。那要怎么用这两个字符呢?
原理
我们约定如下:
ZWJ -> 0ZWSP -> 1ZWNJ -> 无
有一段文本:这是一段示例文案,说明这句话的出处,水印为xxx.com。伪代码:
let zwj = '‍'
let zwsp = '&zwsp;'
let zwnj = '‌'
let dict = {
0: zwj,
1: zwsp,
}
let source = '这是一段示例文案,说明这句话的出处'
let logo = 'xxx.com'
let watermask = log
// 追加
`source${watermask}`
如果这里我们把水印换成1011,我们可以很快的实现:
let logo = '1011'
let watermask = zwsp + zwj + zwsp + zwsp
`source${watermask}` // 这是一段示例文案,说明这句话的出处&zwsp;‍&zwsp;&zwsp;
如果要换成更丰富的水印字符,我们需要有一个作为无的标识,引入了zwnj如下:
let logo = 'ab' // 或者更复杂
let watermask = logo.map(char => tsf(char)).join(zwnj)
// 每个字符转为二进制码
function tsf(char) {
let b = char.charCodeAt().toString(2) // a => 1100001
// 转为零宽字符标识
return b.map(itm => {
return dict[itm]
})
}
总结
整个流程就是
应用场景
注意
这种加密方式虽然一般情况是无感知的,但**如果在有些编辑器中粘贴,是可以看到零宽字符的。**比如开头的截图,浏览器的控制台是可以看到这个字符的。