在数字化和互联网迅速发展的今天,短链接已经成为现代网络应用中不可或缺的一部分。短链接不仅能够节省空间,提高用户体验,还能在社交媒体、短信和二维码中方便地进行分享。然而,生成高效且唯一的短链接并非易事。本文将介绍如何结合 MurmurHash
和 Base62
编码,生成高效、短小且唯一的短链接。
短链接的生成技术广泛应用于以下场景:
MurmurHash
是一种非加密的高效哈希函数,由 Austin Appleby 开发。它主要用于哈希表和数据分布等场景。
在短链接生成中,我们需要一个快速且具有良好分布性的哈希算法。MurmurHash
之所以适合这个任务,主要有以下几个原因:
MurmurHash
设计目标之一就是高效,它能够快速地处理大量数据,适合需要高性能的应用场景。MurmurHash
提供了良好的碰撞概率特性,能够满足这一需求。MurmurHash
的实现简单,易于集成,减少了复杂度并提高了系统的稳定性。Base62
编码是一种将数据压缩成更短字符串的编码方式,它使用 62 个字符:0-9、A-Z 和 a-z。Base62 编码广泛用于生成简短、可读性强的标识符。
结合 MurmurHash
和 Base62
编码,可以实现高效的短链接生成。以下是一个简单的实现工具类。
package com.mps.shortLink.project.toolkit;
import cn.hutool.core.lang.hash.MurmurHash;
/**
* HASH 工具类
*/
public class HashUtil {
private static final char[] CHARS = new char[]{
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'
};
private static final int SIZE = CHARS.length;
private static String convertDecToBase62(long num) {
if (num == 0) return "0"; // 特殊情况处理:当数字为0时,返回"0"
StringBuilder sb = new StringBuilder();
while (num > 0) {
int i = (int) (num % SIZE); // 计算余数
sb.append(CHARS[i]); // 将余数映射到 Base62 字符
num /= SIZE; // 更新数字
}
return sb.reverse().toString(); // 逆序返回 Base62 编码结果
}
public static String hashToBase62(String str) {
int i = MurmurHash.hash32(str); // 使用 MurmurHash 计算字符串的 32 位哈希值
long num = i < 0 ? Integer.MAX_VALUE - (long) i : i; // 将负数转换为非负数
return convertDecToBase62(num); // 将哈希值转换为 Base62 编码的短链接
}
}
convertDecToBase62
方法详解
处理特殊情况:
if (num == 0) return "0";
当 num
为0时,直接返回 “0”。这是为了处理边界情况,确保在所有输入条件下都能返回一个有效的 Base62 编码字符串。
计算 Base62 编码:
StringBuilder sb = new StringBuilder();
while (num > 0) {
int i = (int) (num % SIZE);
sb.append(CHARS[i]);
num /= SIZE;
}
通过取模运算 (num % SIZE
) 和除法运算 (num /= SIZE
) 将数字转换为 Base62 编码。余数 i
被映射到字符数组 CHARS
上,从而生成相应的字符。这个过程反复进行直到 num
变为0。
返回结果:
return sb.reverse().toString();
由于字符是从最低有效位开始添加的,因此需要将字符串反转,以得到正确的 Base62 编码结果。
hashToBase62
方法详解
int i = MurmurHash.hash32(str);
MurmurHash.hash32
方法计算输入字符串 str
的 32 位哈希值。MurmurHash
提供了高效的哈希计算,这里生成的哈希值是一个整数,可能是负数。long num = i < 0 ? Integer.MAX_VALUE - (long) i : i;
i
转换为非负数。如果 i
是负数,则通过 Integer.MAX_VALUE - (long) i
将其映射到正范围内。这一步的目的是确保后续的 Base62 编码操作在非负数上进行。return convertDecToBase62(num);
convertDecToBase62
方法将非负的哈希值 num
转换为 Base62 编码的字符串。convertDecToBase62
方法通过将数字逐步除以 Base62 的基数(62),并将余数映射到字符数组 CHARS
,最终生成短链接。public class ShortLinkService {
public String createShortLink(String longUrl) {
return HashUtil.hashToBase62(longUrl);
}
public static void main(String[] args) {
ShortLinkService service = new ShortLinkService();
String shortLink = service.createShortLink("https://www.example.com");
System.out.println("Short link: " + shortLink);
}
}
在这个示例中,我们通过 HashUtil.hashToBase62
方法生成了一个短链接。生成的短链接字符串更短、更易于使用和分享。
生成的短链接是原始 URL 的哈希值经过 Base62 编码后的结果。例如,将 https://www.example.com
转换为短链接可能得到类似于 aB3kLz
的结果。这个短链接比原始 URL 更短,适合在各种需要短标识符的场景中使用,如社交媒体、二维码和广告追踪等。
MurmurHash
的速度和 Base62
编码的短小特点,能够快速生成短链接。通过结合使用 MurmurHash
和 Base62
编码,我们可以高效生成短链接,解决长 URL 带来的不便。这种方法不仅适用于 URL 缩短,还可以广泛应用于生成唯一标识符和缓存键等场景。如果你对短链接生成有更深入的需求或遇到问题,欢迎在评论区与我讨论!