一、短链接技术
1. 简介
短链接技术是一种将长 URL 映射为短 URL 的技术。简单来说,就是通过一个简化的算法,将输入的长 URL 转换为一个短 URL 字符串,这个字符串可以按照短 URL 本身的需求进行设计,比如可以使用一定的字符集,并且限制字符串长度。
2. 短链接的优点
短链接技术的主要优点包括:
(1)方便用户操作:短链接长度明显较短,让用户更方便地分享 URL 地址。
(2)更美观的外观:短链接不仅方便分享,而且看起来更简洁、美观,更适合用于社交媒体分享等场景。
(3)提高安全性:一旦一个长链接被缩短后,访问者无法通过 URL 字符串中的信息推断出原始 URL 的结构。这提高了 URL 访问的安全性,使其难以被猜测或恶意使用。
3. 短链接的实现方式
短链接的实现方式有很多种,包括:
(1)Hash 算法:将长链接经过 Hash 函数计算得到一个固定长度的值,然后将这个值转换成一个字符串即为短链接。常用的 Hash 算法有 MD5 和 SHA-1 等。
(2)自增ID法:这种方法是取一个自增的 ID 值,将其转为 62 进制表示,并且保存一张映射表,将短链接和长链接进行映射。
(3)图编码法:将长链接对应的二维码图片编码成字符串形式的短链接。这种方法可以很好地解决短链接长度问题。
4. 短链接的应用场景
短链接主要应用于以下场景:
(1)在线广告:短链接可以提高点击率,同时统计用户的点击行为,使得广告主能够更好地了解广告效果。
(2)社交媒体:通过短链接,用户能够方便地分享信息到社交媒体上,尤其是在 Twitter、微博等限制字符数的平台上。
(3)电商平台:短链接可以作为电商平台的推广工具,使得推广信息更容易被用户访问和分享。
二、长链转短链方案
1. 短链接生成原理
在实现 URL 缩短之前,需要先了解 URL 缩短的原理。目前常用的 URL 缩短原理主要有:
(1)Hash 算法
Hash 算法是一种将任意长度的文本映射成固定长度散列值的算法,且散列值的输出具有唯一性。因此,想要再根据散列值还原出原始数据是不可能的。
采用 Hash 算法实现 URL 缩短,首先需要计算出 URL 的 Hash 值,然后将 Hash 值转换为指定字符集的字符串,这个字符串就是短链接。
常见的 Hash 算法有:MD5、SHA1、SHA256 等。但是,Hash 算法虽然能够生成唯一的散列值,但是这些散列值一般都较长,不太适合用于 URL 缩短。
(2)自增 ID 法
自增 ID 法是指,将长链接对应一个自动增加的 ID 值,并将其转为 62 进制表示。例如:0-9a-zA-Z 一共有 62 个字符,任意一个 URL 都可以使用这 62 个字符来表示。
在使用自增 ID 法实现 URL 缩短的时候,需要考虑以下两点:
(a) ID 的生成方式:ID 可以采用数据库中自增 ID 的方式,或者通过 Redis 等缓存服务进行生成。
(b) ID 和长链接的映射关系的存储:ID 和长链接的映射关系可以使用 Redis 进行存储,也可以使用数据库进行存储。
(3)图编码法
图编码法指的是将长链接对应的二维码图片编码成字符串形式的短链接。这个过程可以分为以下两步:
(a) 先将长链接对应的二维码图片生成;
(b) 将二维码图片通过 base64 编码,将编码后的字符串作为短链接。
2. 短链接生成流程
基于前面所介绍的三种短链接生成原理,URL 缩短的基本流程大致如下:
(1)用户输入原始长链接;
(2)调用短链接生成服务;
(3)选择合适的生成方法(Hash 算法、自增 ID 法、图编码法),生成短链接;
(4)将短链接与长链接进行映射,并将其存储到数据库或缓存中;
(5)返回短链接给用户,并将短链接保存在数据库中。
3. 短链接访问流程
当用户使用短链接访问时,基本流程如下:
(1)用户访问短链接地址;
(2)服务器根据短链接查找映射表获取长链接;
(3)服务器进行 3xx 的重定向;
(4)浏览器根据重定向的地址进行跳转。
三、长链转短链代码实现
下面分别介绍 Hash 算法和自增 ID 法实现 URL 缩短的代码实现。
1. 基于Hash算法实现URL缩短
以下是基于 MD5 进行 URL 缩短的 Java 代码实现:
Java
复制代码
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class ShortUrlGenerator {
private static final String ALPHABET = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
private static final int BASE = ALPHABET.length();
public static String getShortUrl(String originalUrl) {
try {
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(originalUrl.getBytes());
byte[] digest = md.digest();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 4; i++) {
int n = ((digest[i] & 0xFF) << 24)
| ((digest[i + 1] & 0xFF) << 16)
| ((digest[i + 2] & 0xFF) << 8)
| ((digest[i + 3] & 0xFF));
sb.append(ALPHABET.charAt(n % BASE));
}
return sb.toString();
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
}
}
代码中的 getShortUrl()
方法计算 URL 的 MD5 值,并将其转换为 4 位字符串作为短链接。由于 MD5 算法的输出值长度为 16 字节(128位),因此可以选择取其中的前 4 个字节进行编码,这样生成的短链接应该已经足够短而不易重复。
2. 基于自增ID实现URL缩短
以下是基于 MySQL 自增 ID 实现 URL 缩短的 Java 代码实现:
Java
复制代码
import java.util.HashMap;
import java.util.Map;
public class ShortUrlGenerator {
private static final String ALPHABET = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
private static final int BASE = ALPHABET.length();
private static final String HOST = "http://short.example.com/";
private static final Long MAX_ID = 100000L;
private Long id = 0L;
private Map<Long, String> urlMap = new HashMap<>();
public String getShortUrl(String originalUrl) {
Long key = id % MAX_ID;
String shortUrl = convertKeyToShortUrl(key);
urlMap.put(id, originalUrl);
id++;
return HOST + shortUrl;
}
private String convertKeyToShortUrl(Long key) {
StringBuilder sb = new StringBuilder();
do {
int index = (int) (key % BASE);
sb.append(ALPHABET.charAt(index));
key /= BASE;
} while (key > 0);
return sb.toString();
}
public String getOriginalUrl(String shortUrl) {
String key = shortUrl.replace(HOST, "");
Long id = convertShortUrlToKey(key);
return urlMap.get(id);
}
private Long convertShortUrlToKey(String shortUrl) {
Long key = 0L;
for (int i = 0; i < shortUrl.length(); i++) {
char c = shortUrl.charAt(i);
int index = ALPHABET.indexOf(c);
if (index < 0) {
throw new IllegalArgumentException("Invalid character in URL");
}
key = key * BASE + index;
}
return key;
}
}
代码中的 getShortUrl()
方法通过保存一个自增 ID 值,在每次调用时生成短链接。ID 可以保存在数据库或缓存中,这里使用 Java 内存。
convertKeyToShortUrl()
方法将 ID 转换为短链接字符串,并按照指定字符集输出,这里采用了与 Hash 算法一致的字符集。
getOriginalUrl()
方法则是根据短链接查找对应的长链接。