使用 Redis 构建短网址生成程序

更新日期: 2019-08-15阅读: 2.7k标签: url

本文摘录自即将出版的《Redis使用手册》, 详情请见: RedisGuide.com 。

为了给用户提供更多发言空间, 并记录用户在网站上的链接点击行为, 大部分社交网站都会将用户输入的网址转换为相应的短网址。 比如说, 如果我们在新浪微博发言时输入网址 http://redisdoc.com/geo/index.html , 那么微博将把这个网址转换为相应的短网址 http://t.cn/RqRRZ8n, 当用户访问这个短网址时, 微博在后台就会对这次点击进行一些数据统计, 然后再引导用户的浏览器跳转到 http://redisdoc.com/geo/index.html 上面。

创建短网址本质上就是要创建出短网址 ID 与目标网址之间的映射, 并在用户访问短网址时, 根据短网址的 ID 从映射记录中找出与之相对应的目标网址。 比如在前面的例子中, 微博的短网址程序就将短网址 http://t.cn/RqRRZ8n 中的 ID 值 RqRRZ8n 映射到了 http://redisdoc.com/geo/index.html 这个网址上面: 当用户访问短网址 http://t.cn/RqRRZ8n 时, 程序就会根据这个短网址的 ID 值 RqRRZ8n , 找出与之对应的目标网址 http://redisdoc.com/geo/index.html , 并将用户引导至目标网址上面去。

作为示例,下图展示了几个微博短网址 ID 与目标网址之间的映射关系:


因为 Redis 的散列正好就非常适合用来储存短网址 ID 与目标网址之间的映射, 所以我们可以基于 Redis 的散列实现一个短网址程序, 例子如下:

使用散列实现的短网址程序: /hash/shorty_url.py

from base36 import base10_to_base36

ID_COUNTER = "ShortyUrl::id_counter"
URL_HASH = "ShortyUrl::url_hash" 

class ShortyUrl:

    def __init__(self, client):
        self.client = client

    def shorten(self, target_url):
        """
        为目标网址创建并储存相应的短网址 ID 。
        """
        # 为目标网址创建新的数字 ID
        new_id = self.client.incr(ID_COUNTER)
        # 通过将 10 进制数字转换为 36 进制数字来创建短网址 ID
        # 比如说,10 进制数字 10086 将被转换为 36 进制数字 7S6
        short_id = base10_to_base36(new_id)
        # 把短网址 ID 用作字段,目标网址用作值,
        # 将它们之间的映射关系储存到散列里面
        self.client.hset(URL_HASH, short_id, target_url)
        return short_id

    def restore(self, short_id):
        """
        根据给定的短网址 ID ,返回与之对应的目标网址。
        """
        return self.client.hget(URL_HASH, short_id)

将 10 进制数字转换成 36 进制数字的程序: /hash/base36.py

def base10_to_base36(number):
    alphabets = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    result = ""

    while number != 0 :
        number, i = divmod(number, 36)
        result = (alphabets[i] + result)

    return result or alphabets[0]

ShortyUrl 类的 shorten() 方法负责为输入的网址生成短网址 ID , 它的工作包括以下四个步骤:

  1. 为每个给定的网址创建一个 10 进制数字 ID 。

  2. 将 10 进制数字 ID 转换为 36 进制, 并将这个 36 进制数字用作给定网址的短网址 ID , 这种方法在数字 ID 长度较大时可以有效地缩短数字 ID 的长度。 代码清单 3-2 展示了将数字从 10 进制转换成 36 进制的 base10_to_base36 函数的具体实现。

  3. 将短网址 ID 和目标网址之间的映射关系储存到散列里面。

  4. 向调用者返回刚刚生成的短网址 ID 。

另一方面, restore() 方法要做的事情和 shorten() 方法正好相反: 它会从储存着映射关系的散列里面取出与给定短网址 ID 相对应的目标网址, 然后将其返回给调用者。

以下代码简单地展示了使用 ShortyUrl 程序创建短网址 ID 的方法, 以及根据短网址 ID 获取目标网址的方法:

>>> from redis import Redis
>>> from shorty_url import ShortyUrl
>>> client = Redis(decode_responses=True)
>>> shorty_url = ShortyUrl(client)
>>> shorty_url.shorten("RedisGuide.com")  # 创建短网址 ID
'1'
>>> shorty_url.shorten("RedisBook.com")
'2'
>>> shorty_url.shorten("RedisDoc.com")
'3'
>>> shorty_url.restore("1")  # 根据短网址 ID 查找目标网址
'RedisGuide.com'
>>> shorty_url.restore("2")
'RedisBook.com'

展示了上面这段代码在数据库中创建的散列结构:


原文:http://blog.huangz.me/2019/redis-shorty-url.html

链接: https://fly63.com/article/detial/4736

静态网站如何获取Get参数,通过js获取url的参数数据的实现方式

不使用动态语言php,java等,直接通过js获取链接中传递的get数据的方法总结。javascript可以获取当前页面的url 只要对获取下来的url进行简单地解析即可。

短网址(short URL)系统的原理及其实现

做一个短链接生成器,可以将一个长链接缩短成一个短链接。就是把普通网址,转换成比较短的网址。好处不言而喻。短、字符少、美观、便于发布、传播。

从浏览器地址栏输入url到显示页面的步骤(以HTTP为例)

在浏览器地址栏输入URL,浏览器查看缓存,如果请求资源在缓存中并且新鲜,跳转到转码步骤,如果资源未缓存,发起新请求,如果已缓存,检验是否足够新鲜,足够新鲜直接提供给客户端,否则与服务器进行验证...

html 获取url地址_js获取当前页面的url网址信息汇总

在WEB开发中,时常会用到javascript来获取当前页面的url网址信息,在这里是我的一些获取url信息的小总结。window.location.href(设置或获取整个 URL 为字符串),window.location.protocol(设置或获取 URL 的协议部分)

html中绝对路径和相对路径的区别?比较相对路径和绝对路径的优缺点

相对路径就是相对于当前文件的路径;可以防止被抄袭,如果网页位置改变,里面的链接还是指向正确的URL。在编码编写时不方便使用绝对路径,因为链接应该指向真正的域名,而不是开发站点。

qs.js_更好的处理url参数

一次接触qs这个库,是在使用axios时,用于给post方法编码,在使用过程中,接触到了一些不同的用法,写在这里分享一下:qs.parse、qs.stringify、排序、指定数组编码格式、处理json格式的参数

短网址(short URL)的实现_如何生成短链接URL?

什么是短链接 ?就是把普通网址,转换成比较短的网址。好处不言而喻:短、字符少、美观、便于发布、传播。所以如何来优雅的生成足够短的字符串唯一ID呢?

window.URL对象的使用方式

window对象的URL对象是专门用来将blob或者file读取成一个url的。这个url可以用在html的任何可以使用url的地方,比如img的src ; audio/video的src和source标签等。

PHP利用get_headers()函数判断远程的url地址是否有效

利用url访问远程的文件、图片、视频时有时需要请求前判断url地址是否有效。利用PHP自带的函数get_headers(),利用http返回值是否存在200状态,来判断url地址是否有效。

URL和URI的区别

URL的格式由下列三部分组成:协议(或称为服务方式);存有该资源的主机IP地址(有时也包括端口号);主机资源的具体地址,如目录和文件名等。URI,统一资源标识符:主机名。存放资源的自身的名称,由路径表示

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!