这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助

发现一个很有创意的小工具网站,如封面图所示功能很简单,就是将一个URL地址转换为都是 ooooooooo 的样子,通过转换后的地址访问可以转换回到原始地址,简单流程如下图所示。转换的逻辑有点像短链平台一样,只不过这个是将你的URL地址变的很长长长长,但是看着都是 ooooooooo,很好奇是如何实现的,所以查阅了源码,本文解读其核心实现逻辑,很有趣且巧妙的实现了这个功能。

前置知识点

在正式开始前,先了解一些需要学习的知识点。因为涉及到两个地址其实也就是字符串之间的转换,会用到一些编码和解码的能力。

将字符转为utf8数组,转换后的每个字符都有一个特定的唯一数值,比如 http 转换后的 utf8 格式数组即是 [104, 116, 116, 112]

    toUTF8Array(str) {
var utf8 = [];
for (var i = 0; i < str.length; i++) {
var charcode = str.charCodeAt(i);
if (charcode < 0x80) utf8.push(charcode);
else if (charcode < 0x800) {
utf8.push(0xc0 | (charcode >> 6),
0x80 | (charcode & 0x3f));
}
else if (charcode < 0xd800 || charcode >= 0xe000) {
utf8.push(0xe0 | (charcode >> 12),
0x80 | ((charcode >> 6) & 0x3f),
0x80 | (charcode & 0x3f));
}
else {
i++;
charcode = ((charcode & 0x3ff) << 10) | (str.charCodeAt(i) & 0x3ff)
utf8.push(0xf0 | (charcode >> 18),
0x80 | ((charcode >> 12) & 0x3f),
0x80 | ((charcode >> 6) & 0x3f),
0x80 | (charcode & 0x3f));
}
}
console.log(utf8, 'utf8');
return utf8;
}

上面是编码,对应下面的则是解码,将utf8数组转换为字符串,比如 [99, 111, 109] 转换后的 utf8 格式数组即是 com

    Utf8ArrayToStr(array) {
var out, i, len, c;
var char2, char3; out = "";
len = array.length;
i = 0;
while (i < len) {
c = array[i++];
switch (c >> 4) {
case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
// 0xxxxxxx
out += String.fromCharCode(c);
break;
case 12: case 13:
// 110x xxxx 10xx xxxx
char2 = array[i++];
out += String.fromCharCode(((c & 0x1F) << 6) | (char2 & 0x3F));
break;
case 14:
// 1110 xxxx 10xx xxxx 10xx xxxx
char2 = array[i++];
char3 = array[i++];
out += String.fromCharCode(((c & 0x0F) << 12) |
((char2 & 0x3F) << 6) |
((char3 & 0x3F) << 0));
break;
}
} return out;
}

将 Number 对象以 4 进制的形式表示为字符串,toString 用的比较多,但是里面传入参数的场景比较少,这个参数 radix 是一个可选的参数,用于指定转换的进制数,范围为 2 ~ 36,如果未传入该参数,则默认使用 10 进制。

n.toString(4)

在字符串左侧填充指定字符,直到字符串达到指定长度。基本语法为 str.padStart(targetLength [, padString])

  • targetLength:必需,指定期望字符串的最小长度,如果当前字符串小于这个长度,则会在左侧使用 padString 进行填充,直到字符串达到指定长度。
  • padString:可选,指定用于填充字符串的字符,默认为 " "(空格)。
str.padStart(4, '0')

URL 编码/解码

下面正式开始URL编码的逻辑,核心的逻辑如下:

  • 转换为utf8数组
  • 转换为4进制并左侧补0到4位数
  • 分割转换为字符串数组
  • 映射到o的不同形式
  • 再次拼接为字符串,即转换完成后的URL
// 获取utf8数组
let unversioned = this.toUTF8Array(url)
// 转换为base 4字符串
// padstart非常重要!否则会丢失前导0
.map(n => n.toString(4).padStart(4, "0"))
// 转换为字符数组
.join("").split("")
// 映射到o的不同形式
.map(x => this.enc[parseInt(x)])
// 连接成单个字符串
.join("")

上面有两个关键点解释一下,首先映射到o的不同形式这个是什么意思呢?其实转换后的o并不是一种“o”,而是4种,只不过我们肉眼看到的效果很像,通过 encodeURI 转换后的字符可以看出来。

encodeURI('o-ο-о-ᴏ')
// o-%CE%BF-%D0%BE-%E1%B4%8F

这里其实也解释了为什么上面为什么是转换为4进制和左侧补0到四位数。因为上面代码定义的 this.enc 如下,因为总共只有四种“o”,4进制只会产生0,1,2,3,这样就可以将转换后的utf8字符一一对应上这几种特殊的“o”。

enc = ["o", "ο", "о", "ᴏ"] 

最后的效果举例转换 http 这个字符:

  • 转换为utf8数组:[ 104, 116, 116, 112 ]
  • 转换为4进制并左侧补0到4位数:['1220', '1310', '1310', '1300']
  • 分割转换为字符串数组:['1', '2', '2', '0', '1', '3', '1', '0', '1', '3', '1', '0', '1', '3', '0', '0']
  • 映射到o的不同形式:[ 'ο', 'о', 'о', 'o', 'ο', 'ᴏ', 'ο', 'o', 'ο', 'ᴏ', 'ο', 'o', 'ο', 'ᴏ', 'o', 'o' ]
  • 再次拼接为字符串,即转换完成后的URL:οооoοᴏοoοᴏοoοᴏoo

到此整个转换编码的过程就结束了,看完后是不是觉得设计的很不错,编码完后就是解码,解码就是将上面的过程倒序来一遍,恢复到最原始的URL地址。这里要注意一点的是每次解析4个字符且parseInt以4进制的方式进行解析。

// 获取url的base 4字符串表示
let b4str = ooo.split("").map(x => this.dec[x]).join("") let utf8arr = []
// 每次解析4个字符
// 记住添加前导0的填充
for (let i = 0; i < b4str.length; i += 4)
utf8arr.push(parseInt(b4str.substring(i, i + 4), 4))
// 返回解码后的字符串
return this.Utf8ArrayToStr(utf8arr)

到此就核心实现代码就分享结束了,看完是不是感觉并没有很复杂,基于此设计或许可以延伸出其他的字符效果,有兴趣的也可以试试看。将转码后的地址分享给你的朋友们一定会带来不一样的惊喜。

下面是我转换的一个AI小工具地址,点击看看效果吧~

ooooooooooooooooooooooo.ooo/ooooοооoοᴏο…

本文转载于:

https://juejin.cn/post/7225573912670191677

如果对您有所帮助,欢迎您点个关注,我会定时更新技术文档,大家一起讨论学习,一起进步。

记录--让URL地址都变成了"ooooooooo"的更多相关文章

  1. JavaWeb工程中url地址的写法

    两种url地址: 1. "/"给服务器使用, 代表web工程根路径(webroot)2. "/"给浏览器使用, 代表tomcat 目录下的webapps文件夹 ...

  2. yii2获取登录前的页面url地址--电脑和微信浏览器上的实现以及yii2相关源码的学习

    对于一个有登录限制(权限限制)的网站,用户输入身份验证信息以后,验证成功后跳转到登录前的页面是一项很人性化的功能.那么获取登录前的页面地址就很关键,今天在做一个yii2项目的登录调试时发现了一些很有意 ...

  3. i春秋url地址编码问题

    i春秋学院是国内比较知名的安全培训平台,前段时间看了下网站,顺便手工简单测试常见的XSS,发现网站搜索功能比较有意思. 其实是对用户输入的内容HTML编码和URL编码的处理方式在这里不合理,提交到乌云 ...

  4. thinkphp的url地址区分大小写?

    在默认情况下: 在访问url地址的时候, 其中的 Action类名 即: 模块名称 是区分大小写的. (只有模块名, 即控制器名称) 可以根据设置 'URL_CASE_INSENSITIVE' =&g ...

  5. git 给远程库 添加多个url地址

     目录[-] 前提 使用流程 原理解析 注意 Other 参考文章 作者:shede333主页:http://my.oschina.net/shede333 && http://blo ...

  6. DNS解析中的A记录、AAAA记录、CNAME记录、MX记录、NS记录、TXT记录、SRV记录、URL转发等

    AA记录: 将域名指向一个IPv4地址(例如:100.100.100.100),需要增加A记录 NSNS记录: 域名解析服务器记录,如果要将子域名指定某个域名服务器来解析,需要设置NS记录 SOASO ...

  7. git 显示多个url地址推送

    前提 一般来说,我们为git增加远程库,一般都是git remote add origin <url> ( 你可以使用真实的地址来代替 \<url\> ) 但是你可能想要把你的 ...

  8. Python处理邮件内容和提取邮件里的url地址

    最近在搞一个邮箱验证账号注册和登录的模块.总结一下.就当记载.文章中涉及到域名和邮箱等都经过处理. 需求是这样子的,注册某个网站的账号,然后注册需要邮件内容激活,登录的时候如果不是常用设备的话也需要认 ...

  9. 【面试题】如何去掉vue的url地址中的#号?及其原理?

    如何去掉vue的url地址中的#号?及其原理? 点击打开视频讲解更加详细 如何去掉vue的url地址中的#号? import Vue from 'vue'; import VueRouter from ...

  10. 注意看,她叫小美,在地址栏输入URL地址后发生了什么?

    注意看,这个用户叫小美,他在地址栏输入了一串URL地址,然后竟然发生了不可思议的事情! 01.输入URL发生了什么? 从输入URL开始,到页面呈现出来,简单来说分为四个步骤: ① 建立连接:建立与服务 ...

随机推荐

  1. Reactive 简介

    1. 概念 Reactive 非常适合低延迟.高吞吐量的工作负载. Reactive Processing 是一种范式(规范),它使开发人员能够构建非阻塞的.异步的应用程序,这些应用程序能够处理背压( ...

  2. 解决邮件客户端QQ Mail及Thunderbird无法登入Outlook的问题

    最近无论是安卓手机的邮件客户端, 或者是 Ubuntu 下的 Thunderbird 都无法登入 Outlook 账号, 原因是需要开启双因素验证. 这个在 Outlook 界面上是不能直接设置的, ...

  3. 用ELK分析每天4亿多条腾讯云MySQL审计日志(3)--下载日志

    当初分析日志,麻烦的是腾讯云的SQL审计日志下载,有下列限制: 1,单次最多1000万条下载 2,单个实例最多生成5条日志文件,多的要先删除以前文件才能生成   腾讯云日志文件生成界面:      一 ...

  4. Oracle 中LONG RAW BLOB CLOB类型介绍

    说明: RAW: 未加工类型,可存储二进制数据或字节符 LONG: 可变长的字符串数据,最长2G,LONG具有VARCHAR2列的特性,可以存储长文本一个表中最多一个LONG列[不建议使用] LONG ...

  5. Go 项目的文件布局

    转自 kcq 的 https://github.com/golang-standards/project-layout https://github.com/golang-standards/proj ...

  6. CentOS8安装Docker报错问题解决

    问题描述 CentOS版本:8.5.2111. # cat /etc/redhat-release CentOS Linux release 8.5.2111 安装准备: # 安装所需软件包 sudo ...

  7. 从零开始写 Docker(二)---优化:使用匿名管道传递参数

    本文为从零开始写 Docker 系列第二篇,主要在 mydocker run 命令基础上优化参数传递方式,改为使用 runC 同款的匿名管道传递参数. 如果你对云原生技术充满好奇,想要深入了解更多相关 ...

  8. gitee配置SSH公钥

    第一步,找个地方打开"git bash",然后输入生成ssh公钥的命令: ssh-keygen -t rsa -C 'your-email' 然后敲四次回车生成公钥: 第二步,输入 ...

  9. os.path.relpath和os.path.basename,返回文件路径中的文件名

    from os import path print(path.relpath("/home/hpcadmin/lw/demo.py", start="/home/hpca ...

  10. 关于centos安装32位兼容库找不到依赖包的问题

    可以看这个博主写的  https://blog.csdn.net/ai74le/article/details/87195077