php-过滤不可见零宽的字符u200B
今天⽤户输⼊了⼀段⽂字:(别辜负了今天。 ),结果触发了业务的产品需求逻辑,不能有四个连续的字符限制,第⼀眼⼀看完全没有连续的啊!
初步猜测是末尾有空格,结果进⾏⽂本删除的时候,发现只有⼀个可见的空格,后⾯末尾出现了四个不可见的0长度的字符,要连续删四次.
⾸先先进⾏问题排查
$content="别辜负了今天。";
$oriJsonContent = json_encode($content);
echo $oriJsonContent;
-----输出-----
"\u522b\u8f9c\u8d1f\u4e86\u4eca\u5929\u3002 \u200b\u200b\u200b\u200b"
此时就发现了末尾出现了不可见0长度的字符\u200B,那么解决思路就有了,过滤掉这个该死的字符即
可解决问题咯
$content = $_POST['content'];
$oriJsonContent = json_encode($content);
if(preg_match("#\\\u200b#us", $oriJsonContent)){
$content = preg_replace("#\\\u200b#us", '', $oriJsonContent);
$content=json_decode($content);
}
PS,这个该死的不可见0宽字符\u200B,还可以⽤来做改名,⽐如王者荣耀,和平精英,或者改名,可以实现改⼀样的名字,或者没有任何字的昵称
————————————华丽的分割线———————————————
零宽度字符在JavaScript中的应⽤
先来看⼀段奇怪代码
上图的字符串中,只看到了3个字符,打印出的length却是10。因为这个字符串中隐藏了7个不可见零宽度字符。
什么是零宽度字符
⼀种不可打印的Unicode字符, 在浏览器等环境不可见, 但是真是存在, 获取字符串长度时也会占位置, 表⽰某⼀种控制功能的字符.
常见的零宽字符有哪些
零宽空格(zero-width space, ZWSP)⽤于可能需要换⾏处。
Unicode: U+200B HTML:
零宽不连字 (zero-width non-joiner,ZWNJ)放在电⼦⽂本的两个字符之间,抑制本来会发⽣的连字,⽽是以这两个字符原本的字形来绘制。
Unicode: U+200C HTML:
零宽连字(zero-width joiner,ZWJ)是⼀个控制字符,放在某些需要复杂排版语⾔(如阿拉伯语、印地语)的两个字符之间,使得这两个本不会发⽣连字的字符产⽣了 Unicode: U+200D HTML:
左⾄右符号(Left-to-right mark,LRM)是⼀种控制字符,⽤于计算机的双向⽂稿排版中。
Unicode: U+200E HTML: 或
右⾄左符号(Right-to-left mark,RLM)是⼀种控制字符,⽤于计算机的双向⽂稿排版中。
Unicode: U+200F HTML: 或
字节顺序标记(byte-order mark,BOM)常被⽤来当做标⽰⽂件是以UTF-8、UTF-16或UTF-32编码的标记。
Unicode: U+FEFF
零宽度字符在JavaScript的应⽤
数据防爬
将零宽度字符插⼊⽂本中,⼲扰关键字匹配。爬⾍得到的带有零宽度字符的数据会影响他们的分析,但不会影响⽤户的阅读数据。
信息传递
将⾃定义组合的零宽度字符插⼊⽂本中,⽤户复制后会携带不可见信息,达到传递作⽤。
使⽤零宽度字符加密解密
信息加密解密的思路是, 把字符串转成⼆进制0和1, 并⽤空格把字符隔开, 然后⽤三种零宽表⽰0、1、空格, 然后⽤第四种零宽字符拼起来;
解密反向操作即可.
代码如下:
// str -> 零宽字符
function strToZeroWidth(str) {
return str
.split('')
.map(char => char.charCodeAt(0).toString(2)) // 1 0 空格
.join(' ')
.split('')
.map(binaryNum => {
if (binaryNum === '1') {
return ''; //
} else if (binaryNum === '0') {
return ''; //
} else {
return ''; //
}
})
.join('') //
}
// 零宽字符 -> str
function zeroWidthToStr(zeroWidthStr) {
return zeroWidthStr
.split('') //
.map(char => {
if (char === '') { //
return '1';
} else if (char === '') { //
return '0';
} else { //
return ' ';
}
})
.join('')
.split(' ')
.map(binaryNum => String.fromCharCode(parseInt(binaryNum, 2)))
.
join('')
}
使⽤:
var str = '我后⾯藏了零宽字符' + strToZeroWidth('im whosmeya');
//undefined
str
//我后⾯藏了零宽字符
str.length //不是9
//180
place(/[^\u200b-\u200f\uFEFF\u202a-\u202e]/g, ""));//解密//im whosmeya
过滤零宽度字符
excel表格 中经常出现零宽字符 \u202c \u202d, 上传后解析或复制到 input 就会有问题,
例如复制 "176xxxx1115" 到控制台获取 length 是 13 ⽽不是 11, 实际字符串⾸尾都被 excel 添加了零宽字符 "\u202d176xxxx1115\u202c".
所以在 excel表格 中获取到的数据⼀般需要先过滤.
提取零宽度字符
如果⽤ 零宽字符 加密信息后插⼊了⽂本中, 解密时需要先吧 零宽字符 提取出来.
_________割__________
/**
* 过滤⾓标过滤零宽字符
phpjson格式化输出* @author repoman
* @param string $str 需要过滤的字符串
* @param string 过滤后的字符串
*/
public function filter_trademark($str){
$str = json_encode($str,true);//转换为Unicode编码
$patterns = []; //正则表达式
$replacements = []; //替换成的字符
/
/公共
$patterns[0] = '/®/';
$replacements[0] = '';
//零宽字符
$patterns[1] = '//';
$replacements[1] = '';
//零宽字符
$patterns[2] = '#\\\u200b#us';
$replacements[2] = '';
$str = preg_replace($patterns, $replacements, $str);
$str = json_decode($str);//解码Unicode编码
return $str;
}
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论