成都网站建设设计

将想法与焦点和您一起共享

java中短网址服务TinyURL生成算法的示例分析

这篇文章给大家分享的是有关java中短网址服务TinyURL生成算法的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。

武强ssl适用于网站、小程序/APP、API接口等需要进行数据传输应用场景,ssl证书未来市场广阔!成为创新互联建站的ssl证书销售渠道,可以享受市场价格4-6折优惠!如果有意向欢迎电话联系或者加微信:13518219792(备注:SSL证书合作)期待与您的合作!

1、生成全局唯一的数字

这本质是一个分布式ID的问题。如果简单处理的话可以借用redis的incr操作这样每次取到的ID都是单调递增且唯一的。另外一种方式是借用MySQL,这里不是借用mysql的主键的auto_incr特性。而是每一台应用来请求时分配一个范围比如 s1 [100-200], s2 来请求的时候就分配 [201-301],本质是利用乐观锁进行一个cas操作。

如果不想借助外部去生成ID的话,可以用UUID算法。UUID长度12个字节组成由,以下几个部分组成。

  • 4个字节表示的Unix timestamp,

  • 3个字节表示的机器的ID

  • 2个字节表示的进程ID

  • 3个字节表示的计数器

UUID是一类算法的统称,具体有不同的实现。优点是每台机器可以独立产生ID,理论上保证不会重复,所以天然是分布式的,缺点是生成的ID太长,不仅占用内存,而且索引查询效率低。

还有一个叫Twitter Snowflake算法,本质上看起来与UUID有些类似。 

java中短网址服务TinyURL生成算法的示例分析

总的来说redis,mysql解决方案就比较简单直接可以满足大部分的场景,如果要保证高性能和高可用的话UUID和Twitter Snowflake算法就更合适,实现起来相对复杂一些。  

2、进制转换

这个操作就相对简单了。直接上代码:

/**
 * 短链接生成
 */
public class TinyURL {
 
  public static final char[] array =
          {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
          'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', 'a', 's', 'd',
          'f', 'g', 'h', 'j', 'k', 'l', 'z', 'x', 'c', 'v', 'b', 'n', 'm',
          'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', 'A', 'S', 'D',
          'F', 'G', 'H', 'J', 'K', 'L', 'Z', 'X', 'C', 'V', 'B', 'N', 'M'};
 
  public static Map charValueMap = new HashMap();
 
  //初始化map
  static {
    for (int i = 0; i < array.length; i++) charValueMap.put(array[i], i);
  }
 
 
  public static void main(String[] args) {
    for (int i = 0; i < 100; i++) {
      long number = Long.MAX_VALUE - i;
      String decimalStr = numberConvertToDecimal(number, 62);
      System.out.println(number + " 转换成 " + decimalStr);
      long toNumber = decimalConvertToNumber(decimalStr, 62);
      System.out.println(decimalStr + " 转换成 " + toNumber);
    }
  }
 
 
  /**
   * 把数字转换成相对应的进制,目前支持(2-62)进制
   *
   * @param number
   * @param decimal
   * @return
   */
  public static String numberConvertToDecimal(long number, int decimal) {
    StringBuilder builder = new StringBuilder();
    while (number != 0) {
      builder.append(array[(int) (number - (number / decimal) * decimal)]);
      number /= decimal;
    }
    return builder.reverse().toString();
  }
 
  /**
   * 把进制字符串转换成相应的数字
   * @param decimalStr
   * @param decimal
   * @return
   */
  public static long decimalConvertToNumber(String decimalStr, int decimal) {
    long sum = 0;
    long multiple = 1;
    char[] chars = decimalStr.toCharArray();
    for (int i = chars.length - 1; i >= 0; i--) {
      char c = chars[i];
      sum += charValueMap.get(c) * multiple;
      multiple *= decimal;
    }
    return sum;
  }
 
 
}

这里面有个小优化就是用charValueMap记录每个字符对应的数值,这是一个用空间换时间的策略优化,把O(n)的时间降为O(1)。

另外通常我们要记录短网址与长网址的对应的关系,相对于直接存储短网址的而言,存储对应的数值ID会更省空间。

感谢各位的阅读!关于“java中短网址服务TinyURL生成算法的示例分析”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,让大家可以学到更多知识,如果觉得文章不错,可以把它分享出去让更多的人看到吧!


网站名称:java中短网址服务TinyURL生成算法的示例分析
分享链接:http://chengdu.cdxwcx.cn/article/ppohjs.html