2018-03-09 15:19:04
TinyURL,短地址,或者叫短链接,指的是一种互联网上的技术与服务。此服务可以提供一个非常短小的URL以代替原来的可能较长的URL,将长的URL地址缩短。
用户访问缩短后的URL时,通常将会重定向到原来的URL。
大多数的URL缩短服务都提供有API。URL缩短服务在Twitter等一些每条消息有字数限制的微博客及其他社交网络中有广泛的使用。
一、TinyURL的兴起原因
由于某些类似于Twitter的微博客服务对于每条贴子或消息有字数限制(多为140字)。某些BBS文章超过一行78个字符时,也会造成一些会自动为网址加上超链接的Telnet及BBS软件无法正确运行该动作,因此需要通过缩短网址的功能来达到网址缩短的目的。
缩址另外也有方便用户记忆及发送网址的功能,短址可将太长的网址转换成15个字以内的替代网址,也有部分网站提供自定义名称以及密码保护的功能,可以让用户获取更有自己风格的短网址。
二、实现算法
问题描述:实现一个算法,将长地址转成短地址。实现长和短一一对应。然后再实现它的逆运算,将短地址还能换算回长地址。
问题求解:
方法一、使用最简单的列表来进行保存,当前的附加位就是其在列表中的序号。这种方法可以很容易的实现长短的转换,但是也有明显的不足。
- 如果我们对同一URL多次进行申请,可以得到多个不同的短链接,这无疑会造成浪费。
- 使用者可以发现已经有多少URL进行过转换了,这个信息是我们不希望用户得到的。
- 或许有人会为了得到一个喜欢的数字,反复不断的进行申请
- 如果仅仅使用数字的话,那么6位数字的表达能力是很差的,最多也就是百万级别,如果加入字母的话效果会好很多。
class Codec: def __init__(self): self.urls = [] def encode(self, longUrl): self.urls.append(longUrl) return 'http://tinyurl.com/' + str(len(self.urls) - 1) def decode(self, shortUrl): return self.urls[int(shortUrl.split('/')[-1])]
方法二、
针对上面提出的各种问题,我们在方法二中会一一解决。
首先是重复问题,对于已经生成的短链接,我们会维护一个longToTiny的hash表,如果当前的长链接已经出现了,那么就直接返回之前生成的TinyURL。
然后是数字的信息泄漏问题,我们这里使用随机数的方法来生成6位的随机数,这里的6位能表达的范围位62^6,是个非常庞大的数字。
最后是使用随机数可能会生成一样的序列,于是采用一个Set来保存已经出现的序列,直到生成未出现的序列。
public class TinyURL { Map<String, String> tinyToLong = new HashMap<String, String>(); Map<String, String> longToTiny = new HashMap<>(); Set<String> flag = new HashSet<>(); // Encodes a URL to a shortened URL. public String encode(String longUrl) { if (longToTiny.containsKey(longUrl)) return longToTiny.get(longUrl); String code = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; String base = "http://tinyurl.com/"; String key = ""; do { for (int i = 0; i < 6; i++) { key += code.charAt((int)Math.random() * code.length()); } } while (flag.contains(key)); flag.add(key); tinyToLong.put(base + key, longUrl); longToTiny.put(longUrl, base + key); return base + key; } // Decodes a shortened URL to its original URL. public String decode(String shortUrl) { return tinyToLong.get(shortUrl); } }