字符ascii码值转换_没想到 Unicode 字符还能这样玩?

92ec862fa92b3e862d86fa82d663c899.png

  脚本之家

你与百万开发者在一起

92ec862fa92b3e862d86fa82d663c899.png

bff405532c33a40ed3df0954109913b5.gif

来源 | 程序通事(ID:US_stocks)

如若转载请联系原公众号

上周的时候,朋友圈的直升飞机不知道为什么就火了,很多朋友开着各种花式飞机带着起飞。

1fb36329dd9f0bc3d288fa1a6488bb87.png
图片来自网络

还没来得及了解咋回事来着,这个直升飞机就?到的微博热搜。

9f30c5f1458b5506020d8082804cf31b.png
图片来自网络

后面越来越多人开来他们的直升飞机,盘旋在朋友圈上方。于是很多朋友开来他们的坦克,专打直升飞机,一轰一个准。

98a08c9fd44b0c2c8b10a415ad61c361.png
图片来自网络

好了,说回正题!

程序员朋友应该都很熟悉 Unicode (万国码),它几乎包含世界上所有符号,比如组成直升飞机这几个特殊符号对应的 Unicode 码分别为:

eb97e822db011161deba97fd324ea62c.png
faa9ccd8e6db209223cf7164e682f348.png

ps:推荐一个网站,可以根据符号搜对应的 Unicode 码:https://unicode.yunser.com/unicode

除了这些正常字符以外,Unicode 还包含着各种各样的奇葩字符。

奇葩字符

除了正常的我们熟知的文字以外,Unicode 中还有一些奇怪的文字,比如下面这些文字

c02acda87e29e45ed92ef8c4dbb16452.png
这咋读?某少?
8040f3133386e2be68b7c84d7d93b7d9.png
世代?
8a59168072836a2f3f03715c5f1ba82f.png
恩?超出认知范围

除了这些奇怪文字以外,Unicode 还有一些奇葩的的符号。

例如下面一整套麻将牌:

43f790a0ecffcb56410e238b6efe73b8.png
三缺一?

一整套的扑克牌:

79b462d7432d4dd51b00598eb1f472c4.png
对三?要不起!

一整套国际象棋:

8d1821081618de484c93792ad2c1814f.png
不会玩--!

除了这些,通过组合符合,我们还可以造出各种各样的颜文字(๑•̀ㅂ•́)و✧、

ce3bc4935a8785c033e062deaca1c210.png

另外 Unicode 还收录着我们常用的 Emoji

6b654e9ef2c4af36c4c2d130bba401bb.png

除了这些之外,Unicode 中还有一些特殊字符的,利用这些字符,我们还可以玩出很多有趣的骚操作。

组合字符

Unicode 有一类字符称为组合字符,它可以附加在前一个非组合字符上,从而使整体看起来像是一个字符。

组合字符原来目的是为了解决一些地区语言、文字特殊的需要,比如说泰文声调符号与母音符号。

c1222a8f8ba1dd59da4667ad32d7e59b.png
39b5be147ea6cfd37130a17fabc5c968.png

正常使用的情况下,这些组合字符数量都会有一些限制。但是在 Unicode 组合字符设计上,并没有加这种限制,这样使我们可以无限加这类组合字符。

利用这个特性,可以达到一些恶搞效果,比如「击穿天花板」与「凿穿地板」的效果。

95502ba3bc07ac25fe40fb0268a43fc1.png

上面实现原理其是利用以下两个组合字符:

ed6231e3ad750e820e6b4a4e98255b2a.png
上翻字符
ce1b9548388bd785b3a9ac4a54ea5fec.png
下翻字符

只要复制这两个字符相应的 HTML 代码,跟在正常的字符后面,就可以使这两个字符附加在普通字符上,比如下面实现效果为

黑̮̑
6efd3212ca215315d5b1d7f2fe29a2f6.png

Unicode 码值通常使用 U+N(16 进制N 代表码值),比如 A 的码值为 U+0041。

在 HTML 中 Unicode 可以使用 N;(十进制,N 代表码值)表示

在 JS 中 Unicode 中需要使用] \uN(16 进制N 代表码值)表示

只要我们在普通字符多复制几个这类附加字符,就可以形成上述「击穿」效果。

还记得上面说的泰文吗,曾经有一段时间贴吧,很流行一种喷射文,比如下面的效果。

 22bafebb06e46aa30b3eb1fc2a59a78b.pngc901cfc4ae3b544fe6eed193b2658d6d.png5e1b942641dbd87dfb4b0b85b830d118.png

往左喷、往右喷、左右互喷

这种喷射文实际原理就是利用泰文中声调符号附加在其他正常符号上。

3a3fcc7fb310f5d2afd18a7a92aa4542.png

不过现在这个效果貌似已经没办法再复现了,现在我们只能看到这样的效果:

2770a897773b867d45da9be691e2921e.png

在一些老版本的系统/浏览器可能还能看到这种效果,知道的小伙伴留言区可以告知一下。

零宽字符

Unicode 中还有一类格式字符,不可见,不可打印,主要作用于调整字符的显示格式,所以我们将其称为零宽字符。

零宽字符主要有以下几类:

零宽度空格符 (zero-width space) U+200B : 用于较长单词的换行分隔

零宽度非断空格符 (zero width no-break space) U+FEFF : 用于阻止特定位置的换行分隔

零宽度连字符 (zero-width joiner) U+200D : 用于阿拉伯文与印度语系等文字中,使不会发生连字的字符间产生连字效果

零宽度断字符 (zero-width non-joiner) U+200C : 用于阿拉伯文,德文,印度语系等文字中,阻止会发生连字的字符间的连字效果

左至右符 (left-to-right mark) U+200E : 用于在混合文字方向的多种语言文本中(例:混合左至右书写的英语与右至左书写的希伯来语),规定排版文字书写方向为左至右

右至左符 (right-to-left mark) U+200F : 用于在混合文字方向的多种语言文本中,规定排版文字书写方向为右至左

利用零宽字符不不可见的特性,我们也可以玩出一些骚效果。

空白微博

发布微博的时候,如果内容都是空格,将没办法发布。

04b8caed44884bdb43d02ac8ab1a9c3d.png

但是如果我们将零宽字符,比如说「零宽度空格符 U+200B」复制到微博,这样我们就可以发布空白微博。

我们可以利用 Chrome 浏览器的控制台复制零宽字符,操作方式如下:

d4a409c9d31dba2b179ed355c0dc4176.png

发布效果如下:

8d3e340131bec2bbe5e620c160b3b8cd.png
真的没有改 HTML 导致的.jpg

隐形水印

对于一些内部论坛或者说小说网站来说,可以通过零宽字符在帖子或小说内容嵌入隐形水印。

当这些内容被一些爬虫复制到其他网站时,我们就可以通过隐形水印,轻松查找时那位用户泄漏内容。

隐形水印主要原理就是将用户信息比如用户名,通过一定算法转成零宽字符,这样普通用户浏览时完全看不到这个水印。

如果内容被复制到其他网站,隐形谁赢也被复制,只要找到这个水印,将这些零宽字符反转成用户名即可。

下面展示一种转换方法,JS 代码主要参考以下 Github 项目:

https://github.com/umpox/zero-width-detection

隐形水印生成方法

第一步我们需要将明文字符串每个字符都转成二进制串。

    // 每个字符转为二进制,用空格分隔
    const textToBinary = username => (
      username
      .split('')
      // charCodeAt 将字符转成相应的 Unicode 码值
      .map(char => char.charCodeAt(0).toString(2))
      .join(' ')
    );

示例如下:

45b5b76daca0e640db68ea139f42c852.png

第二步,将二进制串转为零度字符串,转换规则如下:

  • 1 转换为 \u200b 零宽度字符(zero-width space)
  • 0 转换为 \u200c 零宽度断字符(zero-width non-joiner)
  • 其他(剩余就是空格) 转换为 \u200d 零宽度连字符 (zero-width joiner)
  • 最后使用 \ufeff 零宽度非断空格符 (zero width no-break space) 作为分隔符
const binaryToZeroWidth = binary => (
  binary.split('').map((binaryNum) => {
    const num = parseInt(binaryNum, 10);
    if (num === 1) {
      return '\u200b'; // \u200b 零宽度字符(zero-width space)
    } else if(num===0) {
      return '\u200c'; // \u200c 零宽度断字符(zero-width non-joiner)
    }
    return '\u200d'; // \u200d 零宽度连字符 (zero-width joiner)

  }).join('\ufeff') // \ufeff 零宽度非断空格符 (zero width no-break space)
);

最终加密方法如下:

const encode = username => {
  const binaryUsername = textToBinary(username);
  const zeroWidthUsername = binaryToZeroWidth(binaryUsername);
  return zeroWidthUsername;
};

使用加密方法将明文字符串加密之后,加密字符串肉眼是看不到了,但是实际还是存在的。

12bba952e967a7333674a0173d089517.png

实际上,如果我们将加密之后字符串复制到 ?BEJSON 网站,就可以看到字符。

aa39044bf689ebf6801583bc4dbe0866.png


另外你还可以把加密字符串复制到 IDEA 中,可以看到相应的 Unicode 编码值。

214605fc8c31c6deb1a4e754862e8ab7.png

解密隐形水印

知道了加密的方式,解密其实就很简单,我们只要按照相反步骤的来就可以了。

第一步,将隐形水印按照以下规则转换为二进制串。转换规则如下:

  • 使用 \ufeff 分隔字符串
  • \u200b 转为 1
  • \u200c 转为 0
  • 其他字符使用空格
const zeroWidthToBinary = string => (
  string.split('\ufeff').map((char) => { // \ufeff 零宽度非断空格符 (zero width no-break space)
    if (char === '\u200b') { // \u200b 零宽度字符(zero-width space)
      return '1';
    } else if(char === '\u200c') { // \u200c 零宽度断字符(zero-width non-joiner)
      return '0';
    }
    return ' ';
  }).join('')
);

调用该方法,隐形水印转成二进制串。

d3a355f24b18af7e69c7a81bfedc2edc.png

第二步,将二进制再转为相应的字符。

const binaryToText = string => (
  // fromCharCode 二进制转化
  string.split(' ').map(num => String.fromCharCode(parseInt(num, 2))).join('')
);

最终解密方法如下:

const decode = zeroWidthUsername => {
  const binaryUsername = zeroWidthToBinary(zeroWidthUsername);
  const textUsername = binaryToText(binaryUsername);
  return textUsername;
};

解密示例如下:

237c21ed663bacb400311fe004bbfcf6.png

短网址

我们常用的短网址,域名后面会跟上一串随机串,从而实现短网址到长网址的映射。比如以下网址:

https://sourl.cn/iLyn9S

然而我们可以利用零宽字符也可以实现短网址的效果,,比如下面这个网站,就可以生成这类短网址。

https://zws.im/

eed8510f192fcd3c0a2978ec4504a642.png

可以看到这个短网址后面看不到任何字符,实际上这后面跟着一串零宽字符。当浏览器访问该短网址时,后端程序只要反解密的后面零宽字符,拿到相应的网址,然后在做跳转就可以到指定的网站。

反解密的原理可以参考上面隐形水印的代码

小心零宽字符

日常开发过程中,我们有时需要从一些文件中读取文本内容,然后做相应的处理。

有时候我们可能会碰到一些诡异的现象,比如我们之前碰到的例子。

后台程序从 Excel 读取文本内容,然后程序中判断是读取的文本内容是否与指定的字符串相等。

然后当我们读取一份 Excel 内容后,返现这段比较逻辑怎么也通过不了。本来以为是 Excel 内容存在空格什么的,但是打开 Excel 仔细一看,跟指定字符串一模一样,并没有什么其他字符。

第一次碰到这种例子,没有什么经验,真的排查了很久,到最后都有点怀疑人生了。最后无意间将文本内容复制到了 IDEA 中,才发现整理混杂着零宽字符!

6baefd34d470ca4d671702c2e2465e9a.png

如果各位小伙伴也碰到这类问题,不妨将复制文本内容,然后到 IDEA 中查看是否存在某些看不见字符~

参考链接

  1. https://juejin.im/post/5d3f01e7f265da03c23ead69
  2. http://zero.rovelast.com/
  3. https://zws.im/
  4. https://imweb.io/topic/5a08a5c7ef79bc941c30d8dd
- END -点击卡片进入小程序,签到赢礼品??????

64491d8a73382d8eb6cb6653f79adb88.png

(更多精彩值得期待……)

3e65085073d42cbe11ac76976f84e3f2.gif

f82654739d0ff60305180118fd0cfab5.png8927f7d0d22d327852c8841f334588aa.gif

● b4a371af736ba4109bdfb87033f1cfb8.gif 人人都欠微软一个正版?

● b4a371af736ba4109bdfb87033f1cfb8.gif 积分兑换,来就“兑”了

● b4a371af736ba4109bdfb87033f1cfb8.gif 这 10 行比较字符串相等的代码给我整懵了,不信你也来看看

● b4a371af736ba4109bdfb87033f1cfb8.gif Unicode双向算法(bidi算法)详解(一)

● 漫画:什么是字符串匹配算法?

● 漫画:如何优化 “字符串匹配算法”?

7d22d513ed1fcd9178af5e659c995de8.gif

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/527649.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

右键菜单无响应_被流氓软件玩坏了?这两个清理工具拯救你凌乱的右键菜单。...

Hello 这里是一周进步我们写了四年近2000篇的干货文章,还分享了许多实用的神器工具,一路以来,感谢大家的支持与陪伴~文 / 一周进步 安哥拉如果你和我们一样,是一个喜欢在电脑上安装各种各样的软件的人,你的电脑右键菜…

jsp mysql源码_jsp+servlet+mysql员工管理系统源代码下载

jspservletmysql员工管理系统项目截图注册页面登录页面添加员工编辑员工员工列表数据库建表语句/*Navicat MySQL Data TransferSource Server : localhostSource Server Version : 50509Source Host : localhost:3306Source Database : wdhdbTarget Server Type : MYSQLTarget …

vs里安装了mysql吗_vs2017安装 MySQL for Visual Studio 1.2.

vs2017安装想在win7EF6 VS2017 MySQL 但是安装MySQL for Visual Studio 1.2.7 时一直安装不上去,如下:Action 9:40:05: InstallFinalize.1: Action 9:40:05: DeleteRegKeyAndExtensionsFile_VS2013.1: Action 9:40:06: DeleteRegKeyAndExtensionsFile_…

mysql数据库优化语句_mysql数据库优化语句

mysql优化语句数据库语句: Ddl(数据定义语言) alter create drop Dml(数据操作语言) inset delete update www.2cto.com Dtl(数据事务语言) conmmit rollback savepoint Select Dcl(数据控制语句) grant赋权限 revoke回收 Mysql数据库优化: 1、 数据库表…

json模拟数据怎么用_在使用axios获取自己模拟的json数据是踩到的坑

最近在使用Vue仿写一个网易云音乐的单页面应用,当页面布局什么的写完后,然后就准备用axios获取后台数据渲染页面了,当然,我自己写的,并没有后台,所以,我就自己写json文件,然后弄prox…

mysql架构深入_mysql性能优化2:深入认识mysql体系架构

前言本文将重点梳理mysql的体系架构,便于了解mysql的实现原理。Mysql体系结构Client Connectors 接入方 支持协议很多Management Serveices & Utilities 系统管理和控制工具,mysqldump、 mysql复制集群、分区管理等Connection Pool 连接池&#xff1…

mysql租车管理系统_基于java实现租车管理系统

概述基于java swing JFrame 的图书馆管理系统,租车,还车,管理员管理用户,付款等。部分代码public class Login extends JFrame {private static final long serialVersionUID 1L;/*** 登录窗体*/public Login() {setDefaultClo…

java 1的阶乘之和_1-20的阶乘之和(java)

import java.math.BigInteger;public class Factorial {//2)求1&#xff01;2&#xff01;……20&#xff01;public static void main(String[] args){BigInteger sumBigInteger.ZERO;for(BigInteger iBigInteger.ONE;i.intValue()<20;){ii.add(BigInteger.ONE);sumsum.add…

java构建json_Java构造和解析Json数据的两种方法详解一

在www.json.org上公布了很多JAVA下的json构造和解析工具&#xff0c;其中org.json和json-lib比较简单&#xff0c;两者使用上差不多但还是有些区别。下面首先介绍用json-lib构造和解析Json数据的方法示例。用org.son构造和解析Json数据的方法详解请参见我下一篇博文&#xff1a…

java final被覆盖_java中的final的使用

1、final类不能被继承&#xff0c;因此final类的成员方法没有机会被覆盖&#xff0c;默认都是final的。在设计类时候&#xff0c;如果这个类不需要有子类&#xff0c;类的实现细节不允许改变&#xff0c;并且确信这个类不会再被扩展&#xff0c;那么就设计为final类。(什么时候…

wordcount.java_mapreduce中wordcount的java实现

用java模拟词频统计。有3个文件&#xff1a;text1: hello worldtext2:hello hadooptext3:hello mapreduce对上面的文件进行词频统计&#xff1a;结果应该是&#xff1a;hello:3; hadoop:1; world:1; mapreduce:1代码实现如下&#xff1a;package count;import java.ut…

java程序回滚之后在哪看_Java在触发事务回滚之后为什么会再一次回到Servlet开始的地方重新走一次流程?...

代码流程前台点击"提交订单"进入BaseServlet.classBaseServlet.class分发至子类OrderServlet.class的submitOrder()方法submitOrder()调用Service层的submitOrder()方法.关键是Service层submitOrder()中使用了事务回滚. 这里调用了Dao层两个方法: fun01()和fun02(), …

java不进入for_为什么阿里巴巴Java开发手册中强制要求不要在foreach循环里进行元素的remove和add操作?...

在阅读《阿里巴巴Java开发手册》时&#xff0c;发现有一条关于在 foreach 循环里进行元素的 remove/add 操作的规约&#xff0c;具体内容如下&#xff1a;错误演示我们首先在 IDEA 中编写一个在 foreach 循环里进行 remove 操作的代码&#xff1a;import java.util.ArrayList;i…

8086汇编4位bcd码_二进制格雷码与自然二进制码的互换分析

在精确定位控制系统中&#xff0c;为了提高控制精度&#xff0c;准确测量控制对象的位置是十分重要的。目前&#xff0c;检测位置的办法有两种&#xff1a;其一是使用位置传感器&#xff0c;测量到的位移量由变送器经A/D转换成数字量送至系统进行进一步处理。此方法精度高&…

软件工程结构化建模的方法和工具_软件工程系列-结构化设计方法2

本系列文章为笔记&#xff0c;内容根据北京大学《软件工程》MOOC 初始化模块结构图精化的启发式规则常见的启发式规则什么叫做“启发式”根据设计准则&#xff0c;从长期的软件开发实践中&#xff0c;总结出来的规则既不是设计目标&#xff0c;也不是设计时应该普遍遵循的原理常…

java四种权限的高低_Java(四种权限修饰符)

/*Java中有四种权限修饰符&#xff1a;public > protected > (default) > private同一个类(我自己) YES YES YES YES同一个包(我邻居) YES YES YES NO不同包子类(我儿子) YES YES NO NO不同包非子类(陌生人) YES NO NO NO注意事项&#xff1a;(default)并不是关键字“…

安全扫描失败无法上传_Apache Solr 未授权上传(RCE)漏洞的原理分析与验证

漏洞简介Apache Solr 发布公告&#xff0c;旧版本的ConfigSet API 中存在未授权上传漏洞风险&#xff0c;被利用可能导致 RCE (远程代码执行)。受影响的版本&#xff1a;Apache Solr6.6.0 -6.6.5Apache Solr7.0.0 -7.7.3Apache Solr8.0.0 -8.6.2安全专家建议用户尽快升级到安全…

php session页面传值,PHP session在页面间传递的问题

PHP session在页面间传递的问题:前提: 使用codeIgniter的框架, 使用PHP自带的session1. 在纯apache服务器上没有问题2. 在Nginx的apache模式下, 独立于codeIgniter框架外的页面无问题3. 在Nginx的apache模式下, 置于codeIgniter框架内的页面, 页面间session的传递有问题, 即一个…

html5怎么改为vue_Vue实战——编程式导航打开新窗口,登录状态本地存储

近日来&#xff0c;我陆续的分享了vue相关的系列文章&#xff0c;以新闻列表项目为载体&#xff0c;实战的方式介绍了vue及其周边的技术。本文承接前文&#xff0c;不断通过项目迭代的方式继续分享vue相关的知识。目前Vue实战系列文章已形成了目录&#xff0c;各位感兴趣的朋友…

python转cpp_python转c工具

广告关闭 腾讯云11.11云上盛惠 &#xff0c;精选热门产品助力上云&#xff0c;云服务器首年88元起&#xff0c;买的越多返的越多&#xff0c;最高返5000元&#xff01; compute.proto # python_out目录指定 xxxx_pb2.py的输出路径&#xff0c;我们指定为. 当前路径# grpc_pytho…