一个神奇的小工具,让URL地址都变成了“ooooooooo“

news2024/12/24 20:44:36

转换的逻辑有点像短链平台一样,只不过这个是将你的URL地址变的很长长长长,但是看着都是 ooooooooo,很好奇是如何实现的,所以查阅了源码,本文解读其核心实现逻辑,很有趣且巧妙的实现了这个功能。

发现一个很有创意的小工具网站,如封面图所示功能很简单,就是将一个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;
    }
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.

上面是编码,对应下面的则是解码,「将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;
    }
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.

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

n.toString(4)
  • 1.

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

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

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("")
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.

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

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

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

enc = ["o", "ο", "о", "ᴏ"]
  • 1.

最后的效果举例转换 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)
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.

最后

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

官网地址:「ooooooooooooooooooooooo.ooo」

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

 

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

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

相关文章

kaggle帕金森病进展预测大赛金牌方案分享

赛题背景 帕金森病 &#xff08;PD&#xff09; 是一种致残的脑部疾病&#xff0c;会影响运动、认知、睡眠和其他正常功能。不幸的是&#xff0c;目前没有治愈的方法 - 并且疾病会随着时间的推移而恶化。据估计&#xff0c;到2037年&#xff0c;美国将有1万人患有帕金森病&…

LeetCode 1080. Insufficient Nodes in Root to Leaf Paths【递归,二叉树】中等

本文属于「征服LeetCode」系列文章之一&#xff0c;这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁&#xff0c;本系列将至少持续到刷完所有无锁题之日为止&#xff1b;由于LeetCode还在不断地创建新题&#xff0c;本系列的终止日期可能是永远。在这一系列刷题文章…

【Java|基础篇】详解static关键字和代码块

文章目录 1.前言2.static关键字2.1 static修饰成员变量2.2 static修饰成员方法 3. 代码块3.1 普通代码块3.2 静态代码块3.3 构造代码块 4.总结 1.前言 本文主要讲解static关键字以及代码块的执行顺序以及各部分代码块的作用. 2.static关键字 Java中的static关键字是用来修饰…

hive函数02

hive函数02 窗口函数 窗口函数&#xff08;Window functions )也叫做开窗函数、OLAP函数&#xff0c;其最大特点是∶输入值是从SELECT语句的结果集中的一行或多行的“窗口”中获取的。 窗口函数可以简单地解释为类似于聚合函数的计算函数&#xff0c;但是通过GROUP BY子句组合…

jenkins 常见问题汇总

1、win11 节点&#xff08;Error: Unable to access jarfile slave.jar&#xff09; jenkins 默认cd 进入到设置的目录下面&#xff0c;如果不是C盘的话&#xff0c;直接cd 进入不了其他盘&#xff0c;所以&#xff0c;需要在命令前面&#xff0c;加参数进入到对应盘符。eg:E:…

pandas1

pandas pandas 的核心是&#xff1a;‘Series’、‘DataFrame’、Index’三个类型 1. 创建DataFrame对象 1.1 通过二维数组创建 scores np.random.randint(60,101,(5,3)) scoresarray([[ 91, 87, 87],[100, 80, 61],[ 76, 84, 80],[ 81, 97, 69],[ 67, 77, 65]]…

如何查看SSL证书的有效期?(中科三方)

SSL证书能够对数据传输进行加密处理&#xff0c;对网站的真实性进行核验&#xff0c;是网站提升数据安全能力的重要手段&#xff0c;现在已经有越来越多的网站开始安装SSL证书。但为了保障加密技术的快速更新&#xff0c;SSL证书的有效期逐渐缩短&#xff0c;而一旦SSL证书失效…

【腾讯云 Finops Crane 集训营】心得体会

【腾讯云 Finops Crane 集训营】心得体会 一直在关注技术社区的活动&#xff0c;希望看到更多的新技术&#xff0c;最近在逛 CSDN 的过程中&#xff0c;让我有机会参加了腾讯云的 Finops Crane 开源项目的第一季活动&#xff0c;从而深入了解了这个项目。Crane是一种云资源分析…

PMP常考知识点整理

1十大知识领域之项目整合管理 ❒ 变更控制流程&#xff08;简化版&#xff09; 书面记录变更请求→分析影响→提交CCB进行审批→批准或者拒绝→若批准&#xff0c;先修改计划&#xff08;体现变更&#xff09;&#xff0c;再通知变更受影响相关方&#xff0c;最后再执行、追踪…

【PCIE720】 基于PCIe总线架构的高性能计算(HPC)硬件加速卡

板卡概述 PCIE720是一款基于PCI Express总线架构的高性能计算&#xff08;HPC&#xff09;硬件加速卡&#xff0c;板卡采用Xilinx的高性能28nm 7系列FPGA作为运算节点&#xff0c;在资源、接口以及时钟的优化&#xff0c;为高性能计算提供卓越的硬件加速性能。板卡一共具有5个F…

Linux---文件操作命令(find、which、read)

1. find命令 find [路径] [参数] 要查找的目录路径&#xff0c;可以是一个目录或文件名&#xff0c;也可以是多个路径&#xff0c;多个路径之间用空格分隔&#xff0c;如 果未指定路径&#xff0c;则默认为当前目录。 可选参数&#xff0c;用于指定查找的条件&#xff0c;可…

day37_JQuery

今日内容 零、 复习昨日 一、JQuery 零、 复习昨日 正则 匹配,筛选字符串[0-9a-zA-ZA-z\d\w]*?{3}{4,}{5,10}^$reg.test(字符) jquery js封装的库,封装js操作,可以用来操作事件,dom,动画,ajax$("#id") $("element") $(".class")$("选择器…

chatgpt赋能Python-pythonwhile遍历

Python中使用while循环遍历的优势 Python是一种高级语言&#xff0c;广泛用于Web开发、数据科学、人工智能等方面。Python提供了多种循环结构&#xff0c;其中while循环是一种非常常用的遍历方式。在本篇文章中&#xff0c;我们将介绍如何在Python中使用while循环遍历&#xf…

A2L文件的自动生成(Simulink/CANape)

目录 什么是A2L文件&#xff1f; 使用simulink生成A2L文件 A2L文件组成 characteristic measurement compu_method group simulink生成的A2L与CANape生成的A2L 如何自动修改simulink生成A2L文件使其适用于CANape&#xff1f; 所需文件 什么是A2L文件&#xff1f; A2…

27 KVM管理系统资源-管理虚拟CPU份额

文章目录 27 KVM管理系统资源-管理虚拟CPU份额27.1 概述27.2 操作步骤 27 KVM管理系统资源-管理虚拟CPU份额 27.1 概述 虚拟化环境下&#xff0c;同一主机上的多个虚拟机竞争使用物理CPU。为了防止某些虚拟机占用过多的物理CPU资源&#xff0c;影响相同主机上其他虚拟机的性能…

什么是数字化校园,校园怎么数字化?

教育数字化转型是目前教育领域的一个热门话题&#xff0c;那么到底什么是教育数字化转型&#xff1f;如何做好教育数字化转型&#xff1f;这就来回答一下&#xff01; 阅读本文你将了解&#xff1a; 什么是教育数字化转型&#xff1f;零代码平台如何撬动教育数字化转型&#…

真别去阿里面试,6年测开经验的真实面试经历.....

前几天我朋友跟我吐苦水&#xff0c;这波面试又把他打击到了&#xff0c;做了快6年软件测试员。。。为了进大厂&#xff0c;也花了很多时间和精力在面试准备上&#xff0c;也刷了很多题。但题刷多了之后有点怀疑人生&#xff0c;不知道刷的这些题在之后的工作中能不能用到&…

Linux·eventfd 原理与实践

1. eventfd/timerfd 简介 目前越来越多的应用程序采用事件驱动的方式实现功能&#xff0c;如何高效地利用系统资源实现通知的管理和送达就愈发变得重要起来。在Linux系统中&#xff0c;eventfd是一个用来通知事件的文件描述符&#xff0c;timerfd是的定时器事件的文件描述符。…

防火墙(三)

firewalld防火墙 一、firewalld概述firewalld与iptables的区别firewalld区域firewalld数据处理流程 二、firewalld防火墙的使用配置方法常用的firewalld-cmd命令选项 三、操作小实验 一、firewalld概述 firewalld防火墙是Centos 7 系统默认的防火墙管理工具&#xff0c;取代了…

AWS设备自定义身份认证

AWS设备自定义身份认证需要通过lambda服务实现&#xff0c;具体来说&#xff0c;首先需要创建一个lambda函数&#xff0c;在函数中实现具体的认证逻辑&#xff0c;然后Iot在调用授权方时&#xff0c;将触发lambda函数&#xff0c;返回认证结果。 1.输入参数说明 授权方在调用…