2024-05-06
杂谈
00

目录

第一部分 概述
第二部分 常用方案
2.1 基于时间戳+随机数/计数器
2.2 Base62编码
2.3 自增ID+连续哈希映射
2.4 哈希算法+自定义规则
第三部分 综合方案
3.1 MurmurHash+Base62编码
3.2 自增ID+Base62编码

第一部分 概述

将长链接转换为短链接是一种常见的需求,通常用于在限制长度的场景下分享链接,或者简化链接以提高用户体验。本篇文章讨论几种相对通用的实现方式(第三方服务不在讨论范围)。

第二部分 常用方案

提示

生成短链接时,确保其唯一性和尽可能短是非常关键的。

2.1 基于时间戳+随机数/计数器

方案说明

  • 时间戳: 使用当前时间的时间戳作为基础部分,确保了每个短链接的生成时间不同,自然具有一定的唯一性。
  • 随机数/计数器: 在时间戳基础上附加一个较短的随机数或递增计数器,以应对同一毫秒内生成多个短链接的情况,确保唯一性。

优点

  • 利用时间戳的天然顺序,易于排序和管理。
  • 随机数或计数器的加入,提高了并发情况下的唯一性保障。

缺点

  • 时间戳部分较长,可能影响短链接的简洁度。

2.2 Base62编码

方案说明

  • 将长整型ID(如基于时间戳+计数器生成的ID)转换为Base62编码。Base62包含小写字母、大写字母和数字(共62个字符),比传统的Base16(十六进制)或Base32能更高效地利用字符空间,使得同样的数字可以表示更短的字符串。

优点

  • 极大地缩短了编码长度,提升了短链接的简洁性。
  • 可以通过逆向解码恢复原始ID,便于查询和管理。

缺点

  • 需要处理潜在的冲突问题,尤其是在高并发场景下。

相关信息

Base62是一种将数字和字母混合起来的编码方式,使用了62个字符,包括小写字母、大写字母和数字0-9Base62编码常用于将较长的数字或数据转换为更短、更易于处理和传输的字符串表示形式。

使用场景

  • 短链接生成Base62编码常用于生成短链接,将长网址转换为短字符串,方便分享和传播。短链接不仅更美观,而且更易于记忆和传输,因此在分享网址时非常流行。
  • 密钥生成Base62编码可用于生成密钥或令牌,用于安全验证或身份验证。例如,生成访问令牌、API密钥或会话标识符等。
  • 文件名生成Base62编码可用于生成独一无二的文件名,避免文件名冲突和重复,同时保持文件名的简洁和易读性。
  • 数据转换:在数据传输过程中,Base62编码可用于将二进制数据或大整数转换为字符串形式,方便存储、传输和解析。
  • 短字符串存储:在数据库中存储较短的标识符或键值对时,Base62编码可节省存储空间,并提高查询和索引的效率。

总的来说,Base62编码适用于需要将较长的数字或数据转换为短、易于处理和传输的字符串形式的场景。它具有良好的可读性、节省存储空间的优势,并广泛应用于短链接生成、密钥生成、文件名生成等领域。

2.3 自增ID+连续哈希映射

方案说明

  • 维护一个全局自增ID作为长链接的标识。
  • 使用连续哈希映射(如一致性哈希)将这个ID映射到一个较短的字符串空间中,确保映射的一致性和高效查询。

优点

  • 通过连续哈希映射,可以在保持唯一性的前提下,有效控制短链接的长度。
  • 易于扩展和维护。

缺点

  • 实现相对复杂,需要考虑哈希环的平衡性和扩展性。

相关信息

连续哈希映射是一种多次应用哈希函数的方法,其中每次哈希函数的输出作为下一次哈希函数的输入。通过多次哈希映射,可以进一步增加哈希函数的分散性和唯一性,从而提高哈希算法的安全性和性能。

示例 假设有一个长字符串需要哈希,我们可以将该字符串首先应用第一个哈希函数,然后将结果再次应用到第二个哈希函数,以此类推,直到达到预定的哈希次数或达到某个条件为止。最终的哈希值即为连续哈希映射的结果。

使用场景

  • 密码学中的加密算法:连续哈希映射可以用于密码学中的加密算法,如密码哈希函数。例如,在密码存储过程中,可以多次应用哈希函数对密码进行哈希,增加密码的安全性。
  • 数据完整性校验:在数据传输过程中,可以使用连续哈希映射来对数据进行完整性校验。发送方可以将数据连续哈希映射后的结果附加到数据中,接收方可以再次对接收到的数据应用相同的连续哈希映射,以验证数据的完整性。
  • 分布式系统中的数据分片:在分布式系统中,可以使用连续哈希映射来将数据分配到不同的节点或分片中。通过多次哈希映射,可以使数据更均匀地分布在不同的节点中,提高系统的负载均衡性和性能。

总的来说,连续哈希映射适用于需要增加哈希函数分散性和唯一性的场景,如密码学、数据完整性校验和分布式系统中的数据分片等领域。通过多次应用哈希函数,可以提高数据的安全性、完整性和性能。

2.4 哈希算法+自定义规则

方案说明

  • 使用MD5SHA-256等安全哈希算法处理长链接或其ID,然后取哈希值的前几位作为短链接的基础。
  • 可以根据需要,对哈希值进行自定义规则处理,如替换、移位等,进一步增加唯一性并缩短长度。

Hash算法选择中,通常会使用MurmurHash算法生成长链接的hash值。

优点

  • 哈希算法保证了良好的唯一性。
  • 自定义规则可以灵活调整以适应不同的长度要求。

缺点

  • 存在极小概率的哈希碰撞问题,需要额外机制处理。

相关信息

MurmurHash是一种快速非加密型哈希函数,由Austin Appleby在2008年创建。它被设计用于高速哈希算法中,具有良好的散列性能和低碰撞率。MurmurHash在计算哈希值时非常快速,并且在处理非常大的数据集时具有良好的性能。

简介

MurmurHash算法的核心思想是通过混合、变换和组合输入数据的各个部分来计算哈希值。它采用了一系列位操作、移位操作、异或运算和乘法等简单的数学运算,以及一个具有良好随机性的特定常数作为种子来实现哈希计算。MurmurHash算法的设计目标是高速、可靠和具有良好的分布特性。

适应场景

MurmurHash算法适用于许多场景,包括但不限于:

  • 哈希表:用于实现哈希表数据结构,用于快速查找和存储键值对。
  • 数据分布:用于分布式系统中的数据分区和负载均衡,确保数据分布均匀。
  • 哈希检验:用于数据完整性检验,如校验和计算、文件校验等。
  • 哈希索引:用于构建索引数据结构,提高检索效率。

优点

  • 速度快MurmurHash算法在计算哈希值时非常快速,适用于需要高效处理大量数据的场景。
  • 低碰撞率MurmurHash算法具有良好的散列性能,碰撞率较低,适用于要求较高的哈希算法场景。
  • 分布均匀MurmurHash算法生成的哈希值分布均匀,有利于提高数据的均匀分布性,降低哈希冲突的概率。

总结

MurmurHash算法是一种快速、可靠且具有良好散列性能的哈希算法,适用于各种需要哈希计算的场景。它的速度快、碰撞率低以及分布均匀等特点使得它成为了许多哈希算法的首选之一。无论是在哈希表、数据分布、哈希检验还是哈希索引等领域,MurmurHash都展现出了出色的性能和应用价值。

第三部分 综合方案

在实际应用中,通常会结合上述多种方法,例如先使用时间戳加计数器生成ID,然后将ID进行Base62编码,同时设计一套冲突检测和解决机制(如在数据库中检查ID是否已存在),确保生成的短链接既唯一又尽量短。此外,还可以引入布隆过滤器等数据结构来快速判断ID是否存在,减少数据库查询压力。

3.1 MurmurHash+Base62编码

使用MurmurHashBase62结合的方法生成短链接是一种常见的做法,这样可以保证生成的短链接具有较高的唯一性和易读性。下面是使用MurmurHashBase62结合的方法生成短链接的示例代码:

java
long hash = MurmurHash.hash32("https://blog.jianggujin.com/post/5"); System.out.println("长链接hash:" + hash); byte[] bytes = ByteBuffer.allocate(Long.BYTES).putLong(hash).array(); String encoded = Base62.encode(bytes); System.out.println("转换后编码:" + encoded); hash = MurmurHash.hash64("https://blog.jianggujin.com/post/5"); System.out.println("长链接hash:" + hash); bytes = ByteBuffer.allocate(Long.BYTES).putLong(hash).array(); encoded = Base62.encode(bytes); System.out.println("转换后编码:" + encoded);

运行示例代码观察控制台输出

长链接hash:640577084 转换后编码:0000hLnMS 长链接hash:-4731572046405325430 转换后编码:GL9dGlAe8Yk

示例代码中的MurmurHashBase62使用hutool工具实现,在进行hash处理时,可根据实际情况选择hash32hash64

注意

虽然MurmurHashBase62结合的方式生成短链接具有较高的唯一性,依然存在冲突的可能,在实际使用过程中需要考虑发生冲突后的处理,比如增加自增整数等。

3.2 自增ID+Base62编码

使用自增IDBase62结合的方法生成短链接是另一种常见的做法,相较于使用MurmurHashBase62结合的方法,采用自增ID的方式可确保生成的短链的唯一性。自增ID的生成可以利用数据库、Redis、雪花算法等方式生成。下面是使用雪花算法和Base62结合的方法生成短链接的示例代码:

java
long hash = IdWorker.getId(); System.out.println("长链接hash:" + hash); byte[] bytes = ByteBuffer.allocate(Long.BYTES).putLong(hash).array(); String encoded = Base62.encode(bytes); System.out.println("转换后编码:" + encoded);

运行示例代码观察控制台输出

长链接hash:1787313950076686338 转换后编码:281uqNpdic6

使用自增IDBase62结合的方式,短链接的hash值的生成与链接本身无关

如果对你有用的话,可以打赏哦
打赏
ali pay
wechat pay

本文作者:蒋固金

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!