什么零寬度字符,以及零寬度字符在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('')
}

使用:

過濾零寬度字符

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, "");

whosmeya.com


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM