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
zeroWidthToStr(str.replace(/[^\u200b-\u200f\uFEFF\u202a-\u202e]/g, ""));//解密
//im whosmeya

过滤零宽度字符

excel表格 中经常出现零宽字符 \u202c \u202d, 上传后解析或复制到 input 就会有问题,

例如复制 "‭176xxxx1115‬" 到控制台获取 length 是 13 而不是 11, 实际字符串首尾都被 excel 添加了零宽字符 "\u202d176xxxx1115\u202c".

所以在 excel表格 中获取到的数据一般需要先过滤.

str.replace(/[\u200b-\u200f\uFEFF\u202a-\u202e]/g, "");

提取零宽度字符

如果用 零宽字符 加密信息后插入了文本中, 解密时需要先吧 零宽字符 提取出来.

str.replace(/[^\u200b-\u200f\uFEFF\u202a-\u202e]/g, "");

_________割__________   

     /**
     * 过滤角标过滤零宽字符
     * @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;
    }

 

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值