我們來玩個找茬兒,看看下面這段代碼,找找 md5 函數的定義在哪裏:
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8">
</head>
<body>
<script>
Function("".replace(/.{8}/g,function(u)
{return String.fromCharCode(parseInt(u.
replace(/\u200c/g,1).replace(/\u200d/g,
0),2))}))();
</script>
<script>
alert( md5( "hello" ) );
</script>
</body>
</html>
太棒了,我知道難不倒你,10 秒鐘就找出來了是不是?好吧,可能我舉了一個不是很好的例子,因爲它一點用處都沒有。
標題裏的“短”字加了引號,只是因爲它看起來短,實際並不短,因爲字節還是在的,在 unicode 裏有一種神奇的字符叫零寬空白,它的特點是字型的顯示寬度爲 0,無論堆了多少個零寬字符,你都看不見它。
就像上面我寫的例子中,Function("<這裏>".repla...
藏了大量的零寬字符,實際看起來就好像是一個空字符串 ""
,這個“空”字串即是
md5 的函數定義經過編碼轉換後得到的全零寬字符串,此創意最初源自一個叫 z.js 的庫。
每個字符都有一個唯一的編碼,將編碼以 2 進製表示得到 01.. 的字串,把 1 替換成 U+200C,把 0 替換成 U+200D 就得到一個全零寬空白的字符串,每 8 位零寬字符可用於表示 1 個 ascii 字符,所以例子當中,理論上是變長的,不算解碼程序的 129 個字符,僅空白就佔了原文 8 倍的體積,如果出現中文,那就更不止了,因爲中文已經超過了 ascii 的範圍,需要先轉成純 ascii (如以 \uxxxx 表示)後再處理。
在 unicode 裏,至少有 U+200B, U+200C, U+200D 和 U+FEFF 四個零寬字符,如果把這 4 個字符全用上,上面的例子又可以減少 1 半的體積,感興趣的同學自己折騰下。
最後,隱藏代碼是不科學的,零寬字符有其它更多更有意義的使用場景,比如用於本地存貯的敏感數據等,遊戲裏面應該會有需求,就看你的發揮了。
另:該文章是從知乎回答裏的評論看到的,該回答提供的代碼是將自己點贊
Function("".replace(/.{8}/g,function(u){return String.fromCharCode(parseInt(u.replace(/\u200c/g,1).replace(/\u200d/g,0),2))}))();
回答鏈接 http://www.zhihu.com/question/26483508
轉自 http://ucren.com/blog/archives/549
作者 dron