打造高效短网址|Base62编码工程实战案例

一、为什么需要短网址?

在现代社会,short url已不仅仅是保存空间和排版考虑的问题,更是一种需要在多个媒介传播的新闻、信息、产品宣传、宣传语的一种需求。

而常规的短网址转换基本都是通过跳转的方式实现,虽然看起来简单,但是每一个链接都要跳转一次,跳转次数多了还会给用户带来额外的时间成本,对于大流量网站而言,跳转次数多了会对服务器带来极大的负担,而且有时候并不是用户希望得到的目标页面,这时候就需要一种更有效的方式来实现短网址跳转。

此时就需要有一种更加高效和可靠的实现方式,比如 Base62 编码就是一种非常好的选择。

二、什么是Base62编码?

Base62编码是一种62进制的编码方式,使用数字、大小写字母来表示一个数字。

简单来说,就是将10进制的数字通过转换,用短字符串来表示该数字。可用于生成短网址、生成UID等场景。

Base62编码的值域为0-9a-zA-Z,共计62个字符,由于62的6次方比16的8次方大,所以base62在相同长度情况下能够表示的数字比base16要多得多,而且它的字符串相对长度也要短得多。

三、如何使用Base62编码实现短网址?

首先,我们需要将原始url转换为短码,以便在跳转时使用。一个有效的短网址方案应该包括以下两个环节。

第一步:生成短码:将原始长链接转换为短码。我们可以根据原始URL生成MD5值,然后通过Base62编码生成短码。

// 使用md5可以得到一个128位的哈希值,但使用Base62编码后只需要6位
unsigned char result[16];
md5(input, strlen(input), result);

// 计算生成的短码(使用 Base62 编码),即将 10 进制转换为 62 进制
std::string urlcode = hex2dec(result, sizeof(result));
std::string short_code = encode_base62((int)strtol(urlcode.c_str(), NULL, 16));

第二步:解析短码:请求缩短的短码,解析并有效的301定向到原始的长链接,这是一个经典的请求转发模式。

// 解析 Base62 编码得到 10 进制
unsigned long long count = decode_base62(shortCode);
std::stringstream ss;
ss << std::hex << count;
std::string s = ss.str();

// 补齐位数
std::string md5result(32 - s.length(), '0');
md5result = md5result + s;

// 将 16 进制字符串转换成 unsigned char[]
unsigned char result[16];
for (int i = 0; i < 16; i++)
{
    std::string sub = md5result.substr(i * 2, 2);
    result[i] = (unsigned char)strtol(sub.c_str(), NULL, 16);
}

// 通过 MD5 解析得到原始 URL
std::string url = md5_to_url(result);

通过以上两个步骤,我们就可以方便地将长链接转换为短链接,从而提高跳转效率。

四、完整代码示例

下面为完整的代码示例,包括了使用MD5生成哈希值以及Base62编码的实现。

#include <iostream>
#include <string>
#include <cstring>
#include <climits>
#include <cmath>
#include <algorithm>
#include <sstream>

const std::string base62_chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";

// Base62 编码
std::string encode_base62(unsigned long long number)
{
    std::string base62_str;
    do
    {
        base62_str.push_back(base62_chars[number % 62]);
        number /= 62;
    } while (number);

    std::reverse(base62_str.begin(), base62_str.end());
    return base62_str;
}

// Base62 解码
unsigned long long decode_base62(std::string const& str)
{
    unsigned long long number = 0;
    for (int i = 0; i = '0' && h1 = 'A' && h1 <= 'F'))
            *ptr = (h1 <= '9') ? (h1 - '0') : (h1 - 'A' + 10);
        else
            break;

        *ptr <= '0' && h2 = 'A' && h2 <= 'F'))
            *ptr |= (h2 <= '9') ? (h2 - '0') : (h2 - 'A' + 10);
        else
            break;

        ptr++;
    }

    return dest;
}

// 使用md5计算哈希值
void md5(const char* str, size_t len, unsigned char* result)
{
    EVP_MD_CTX* ctx = EVP_MD_CTX_new();
    EVP_DigestInit_ex(ctx, EVP_md5(), NULL);
    EVP_DigestUpdate(ctx, str, len);
    EVP_DigestFinal_ex(ctx, result, NULL);
    EVP_MD_CTX_free(ctx);
}

// 将 md5 值转换成 URL
std::string md5_to_url(unsigned char* result)
{
    std::stringstream ss;
    for (int i = 0; i < 16; i++)
        ss << std::hex << (int)result[i];

    std::string url = ss.str();
    return url.substr(0, 8) + "-" + url.substr(8, 4) + "-" + url.substr(12, 4) + "-" + url.substr(16, 4) + "-" + url.substr(20);
}

int main()
{
    // 待转换的 URL
    std::string input = "https://www.google.com/";

    // 使用 md5 可以得到一个128位的哈希值,但使用 Base62 编码后只需要6位
    unsigned char result[16];
    md5(input.c_str(), input.length(), result);

    // 计算生成的短码(使用 Base62 编码),即将 10 进制转换为 62 进制
    std::string urlcode = hex2dec(result, sizeof(result));
    std::string short_code = encode_base62((int)strtol(urlcode.c_str(), NULL, 16));

    std::cout << "Short URL: " << short_code << std::endl;

    // 解析 Base62 编码得到 10 进制
    unsigned long long count = decode_base62(short_code);
    std::stringstream ss;
    ss << std::hex << count;
    std::string s = ss.str();

    // 补齐位数
    std::string md5result(32 - s.length(), '0');
    md5result = md5result + s;

    // 将 16 进制字符串转换成 unsigned char[]
    unsigned char result2[16];
    for (int i = 0; i < 16; i++)
    {
        std::string sub = md5result.substr(i * 2, 2);
        result2[i] = (unsigned char)strtol(sub.c_str(), NULL, 16);
    }

    // 通过 MD5 解析得到原始 URL
    std::string url = md5_to_url(result2);
    std::cout << "Original URL: " << url << std::endl;

    return 0;
}

原创文章,作者:BVMQC,如若转载,请注明出处:https://www.506064.com/n/324850.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
BVMQCBVMQC
上一篇 2025-01-13 13:23
下一篇 2025-01-13 13:23

相关推荐

  • Python数据统计案例的实现

    Python作为一个高级编程语言,拥有着丰富的数据处理库和工具,能够快速、高效地进行各类数据处理和分析。本文将结合实例,从多个方面详细阐述Python数据统计的实现。 一、数据读取…

    编程 2025-04-29
  • Django框架:从简介到项目实战

    本文将从Django的介绍,以及如何搭建Django环境开始,逐步深入到Django模型、视图、模板、表单,最后通过一个小型项目实战,进行综合性的应用,让读者获得更深入的学习。 一…

    编程 2025-04-28
  • Trocket:打造高效可靠的远程控制工具

    如何使用trocket打造高效可靠的远程控制工具?本文将从以下几个方面进行详细的阐述。 一、安装和使用trocket trocket是一个基于Python实现的远程控制工具,使用时…

    编程 2025-04-28
  • 键值存储(kvs):从基础概念到实战应用

    本文将从基础概念入手,介绍键值存储(kvs)的概念、原理以及实战应用,并给出代码实现。通过阅读本文,您将了解键值存储的优缺点,如何选择最适合的键值存储方案,以及如何使用键值存储解决…

    编程 2025-04-28
  • Python编程实战:用Python做网页与HTML

    Python语言是一种被广泛应用的高级编程语言,也是一种非常适合于开发网页和处理HTML的语言。在本文中,我们将从多个方面介绍如何用Python来编写网页和处理HTML。 一、Py…

    编程 2025-04-28
  • Python生成列表最高效的方法

    本文主要介绍在Python中生成列表最高效的方法,涉及到列表生成式、range函数、map函数以及ITertools模块等多种方法。 一、列表生成式 列表生成式是Python中最常…

    编程 2025-04-28
  • yarn npm 仓库用法介绍及使用案例

    本文将从多个方面对yarn npm仓库进行详细阐述,并为你提供一些实际使用案例。 一、npm和yarn的比较 npm和yarn都是JavaScript的包管理工具。npm在Java…

    编程 2025-04-27
  • Webrtc音视频开发React+Flutter+Go实战PDF

    本文将从多个方面介绍如何使用React、Flutter和Go来进行Webrtc音视频开发,并提供相应的代码示例。 一、Webrtc音视频开发介绍 Webrtc是Google开发的一…

    编程 2025-04-27
  • TFN MR56:高效可靠的网络环境管理工具

    本文将从多个方面深入阐述TFN MR56的作用、特点、使用方法以及优点,为读者全面介绍这一高效可靠的网络环境管理工具。 一、简介 TFN MR56是一款多功能的网络环境管理工具,可…

    编程 2025-04-27
  • Python自动化交易实战教程

    本教程将详细介绍使用Python进行自动化交易的方法,包括如何选择优秀的交易策略、如何获取市场数据、如何实现策略并进行回测,以及如何使用Python自动化下单,并进行实盘交易,让您…

    编程 2025-04-27

发表回复

登录后才能评论