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

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

在这里插入图片描述
     最近发现一个有意思工具,就是将一个URL地址转换为都是 ooooooooo 的样子,通过转换后的地址访问可以转换回到原始地址,转换的逻辑有点像短链平台一样,但是这个工具他是将你的URL地址变的很长长长长,但是看着都是 ooooooooo,个人觉得蛮有意思的,于是找到了它的源码仓库,便查阅了一番。顺便给大家讲讲实现逻辑。

一、核心代码

     涉及到两个地址其实也就是字符串之间的转换,会用到一些编码和解码。

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

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;
    }

二、URL编码/解码

  1. 转换为utf8数组
  2. 转换为4进制并左侧补0到4位数
  3. 分割转换为字符串数组
  4. 映射到o的不同形式
  5. 再次拼接为字符串,即转换完成后的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", "ο", "о", "ᴏ"] 

上述编码之后,还不能正常访问,想正常访问还需拼接一些东西:

let url = 'https://ooooooooooooooooooooooo.ooo/oooo'+ this.unversioned;

     编码完后就是解码,解码就是将上面的过程倒序来一遍,恢复到最原始的URL地址。这里要注意一点的是每次解析4个字符且parseInt以4进制的方式进行解析。

let b4str = ooo.split("").map(x => this.dec[x]).join("")
let utf8arr = []

// parse 4 characters at a time (255 in b10 = 3333 in b4)
// remember adding leading 0s padding
for (let i = 0; i < b4str.length; i += 4)
    utf8arr.push(parseInt(b4str.substring(i, i + 4), 4))
return this.Utf8ArrayToStr(utf8arr)

注意,解码时变量ooo是没有拼接东西的,也就是说它是编码时 unversioned的结果。如果拼接了东西,学把拼接的字符截取后在进行解码。

下面是我转换的一个在线工具地址,点击看看效果吧~
ooooooooooooooooooooooo.ooo/ooooοооoοᴏο…

以下是一个简单的C语言程序,可以在Windows平台上实现放烟花的效果: ```c #include <stdio.h> #include <stdlib.h> #include <windows.h> int main() { int x, y, i, j; system("mode con:cols=100 lines=40"); // 设置窗口大小 srand((unsigned)time(NULL)); // 随机数种子 while (1) { x = rand() % 100; // 随机生成烟花的位置 y = rand() % 30 + 10; for (i = 1; i <= 20; i++) { // 循环20次,模拟烟花的爆炸过程 for (j = 1; j <= 36; j++) { if (j >= i && j <= 36 - i) { SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), i * 10 + j % 10); // 设置字体颜色 printf("o"); // 输出烟花 } else { printf(" "); // 输出空格 } } printf("\n"); Sleep(50); // 等待一段时间 } for (i = 1; i <= 30; i++) { // 清空屏幕 printf("\n"); } SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), (COORD){ x, y }); // 设置光标位置 printf("☆"); // 输出烟花的中心点 Sleep(500); // 等待一段时间 } return 0; } ``` 运行程序后,会在命令行窗口中不停地放烟花,效果如下: ``` o ooo oooooo oooooooo ooooooooo ooooooooooo oooooooooooooo oooooooooooooooo ooooooooooooooooo ooooooooooooooooooo ooooooooooooooooooooo ooooooooooooooooooooooo oooooooooooooooooooooooo ooooooooooooooooooooooooo ooooooooooooooooooooooooooo oooooooooooooooooooooooooooo ooooooooooooooooooooooooooooo ooooooooooooooooooooooooooooooo oooooooooooooooooooooooooooooooo ooooooooooooooooooooooooooooooooo ooooooooooooooooooooooooooooooooooo oooooooooooooooooooooooooooooooooooo ooooooooooooooooooooooooooooooooooooo ooooooooooooooooooooooooooooooooooooooo oooooooooooooooooooooooooooooooooooooooo ooooooooooooooooooooooooooooooooooooooooo ooooooooooooooooooooooooooooooooooooooooooo oooooooooooooooooooooooooooooooooooooooooooo ooooooooooooooooooooooooooooooooooooooooooooo ooooooooooooooooooooooooooooooooooooooooooooooo oooooooooooooooooooooooooooooooooooooooooooooooo ooooooooooooooooooooooooooooooooooooooooooooooooo ooooooooooooooooooooooooooooooooooooooooooooooooooo oooooooooooooooooooooooooooooooooooooooooooooooooooo ooooooooooooooooooooooooooooooooooooooooooooooooooooo ooooooooooooooooooooooooooooooooooooooooooooooooooooooo oooooooooooooooooooooooooooooooooooooooooooooooooooooooo ooooooooooooooooooooooooooooooooooooooooooooooooooooooooo ooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo ooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo ooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo ooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo ☆ ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值