资讯专栏INFORMATION COLUMN

聊聊base62与tinyURL

phoenixsky / 512人阅读

摘要:进制转进制也类似,从右往左每个数的次方,从开始。短的转换主要思路,维护一个全局自增的,每来一个长,将其与一个自增绑定,然后利用将该自增转换为字符串,即完成转换。测试关于容量自增为型,最大如何设计短网址系统

base64大家肯定是很熟悉了,那base62是什么东东,它常被用来做短url的映射。

ascii编码的62个字母数字
Value Encoding  Value Encoding  Value Encoding  Value Encoding
  0 a            17 r            34 I            51 Z
  1 b            18 s            35 J            52 0
  2 c            19 t            36 K            53 1
  3 d            20 u            37 L            54 2
  4 e            21 v            38 M            55 3
  5 f            22 w            39 N            56 4
  6 g            23 x            40 O            57 5
  7 h            24 y            41 P            58 6
  8 i            25 z            42 Q            59 7
  9 j            26 A            43 R            60 8
 10 k            27 B            44 S            61 9
 11 l            28 C            45 T
 12 m            29 D            46 U
 13 n            30 E            47 V
 14 o            31 F            48 W
 15 p            32 G            49 X
 16 q            33 H            50 Y

26个小写字母+26个大写字母+10个数字=62

    public static final String BASE_62_CHAR = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
    public static final int BASE = BASE_62_CHAR.length();
62进制与十进制的映射 62进制转10进制

还记得二进制转十进制的算法么,从右到左用二进制的每个数去乘以2的相应次方,次方要从0开始。62进制转10进制也类似,从右往左每个数*62的N次方,N从0开始。

    public static long toBase10(String str) {
        //从右边开始
        return toBase10(new StringBuilder(str).reverse().toString().toCharArray());
    }

    private static long toBase10(char[] chars) {
        long n = 0;
        int pow = 0;
        for(char item: chars){
            n += toBase10(BASE_62_CHAR.indexOf(item),pow);
            pow++;
        }
        return n;
    }

    private static long toBase10(int n, int pow) {
        return n * (long) Math.pow(BASE, pow);
    }
十进制转62进制

还记得十进制转二进制的算法么,除二取余,然后倒序排列,高位补零。转62进制也类似,不断除以62取余数,然后倒序。

    public static String fromBase10(long i) {
        StringBuilder sb = new StringBuilder("");
        if (i == 0) {
            return "a";
        }
        while (i > 0) {
            i = fromBase10(i, sb);
        }
        return sb.reverse().toString();
    }

    private static long fromBase10(long i, final StringBuilder sb) {
        int rem = (int)(i % BASE);
        sb.append(BASE_62_CHAR.charAt(rem));
        return i / BASE;
    }
短url的转换

主要思路,维护一个全局自增的id,每来一个长url,将其与一个自增id绑定,然后利用base62将该自增id转换为base62字符串,即完成转换。

public class Base62UrlShorter {

    private long autoIncrId = 10000;

    Map longUrlIdMap = new HashMap();

    public long incr(){
        return autoIncrId ++ ;
    }

    public String shorten(String longUrl){
        long id = incr();
        //add to mapping
        longUrlIdMap.put(id,longUrl);
        return Base62.fromBase10(id);
    }

    public String lookup(String shortUrl){
        long id = Base62.toBase10(shortUrl);
        return longUrlIdMap.get(id);
    }
}

测试

    @Test
    public void testLongUrl2Short(){
        Base62UrlShorter shorter= new Base62UrlShorter();
        String longUrl = "https://movie.douban.com/subject/26363254/";
        String shortUrl = shorter.shorten(longUrl);
        System.out.println("short url:"+shortUrl);
        System.out.println(shorter.lookup(shortUrl));
    }
关于容量

自增id为long型,最大2^64 -1

doc

534. Design TinyURL

如何设计短网址系统(TinyURL)

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/67549.html

相关文章

  • 聊聊jdk httpclient的connect timeout异常

    摘要:序本文主要研究一下的异常实例代码异常日志如下最后调用这里调用获取连接如果没有连接会新创建一个,走的是这里先是调用了获取连接,然后调用进行连接这里委托给这里如果有设置的话,则会创建一个调用进行连接,如果连接未 序 本文主要研究一下httpclient的connect timeout异常 实例代码 @Test public void testConnectTimeout()...

    张利勇 评论0 收藏0
  • Base62x比Base64的编码速度更快吗?

    摘要:比如其中一个的应用场景,在中取代的改进使用的方案是从代码层分析耗时差值原因,尽管两者都使用了位操作进行计算,但在单位编码长度上多了数值判断,由此导致其速度下降。 现在几乎所有企事业单位、政府机构、军工系统等的IT生产系统都会用到Base64编码,从RSA安全密钥到管理信息系统登录入口回跳,目前越来越多的IT系统研发者开始使用 Base62x 替换 Base64. -Base62x 提供...

    tainzhi 评论0 收藏0
  • -Base62x 新增 -Perl 版本技术实现 Base62x.pm

    摘要:同的其他版本相通,实现了跨编程语言运行时环境的数据安全交换。函数式编程的除了式的写法,还提供了函数式编程的调用方式,列如下。函数式编程适合单一次启动并运行的使用场景。 在此前的一篇Blog(-R/G2SW )中,-gMIS 吉密斯优化更新+分组项区段AddGroupBySeg/+复制AddByCopy等, 我们提到注册动作registerAct: 改进增加 Base62x.class....

    WelliJhon 评论0 收藏0
  • -Base62x 新增 -Perl 版本技术实现 Base62x.pm

    摘要:同的其他版本相通,实现了跨编程语言运行时环境的数据安全交换。函数式编程的除了式的写法,还提供了函数式编程的调用方式,列如下。函数式编程适合单一次启动并运行的使用场景。 在此前的一篇Blog(-R/G2SW )中,-gMIS 吉密斯优化更新+分组项区段AddGroupBySeg/+复制AddByCopy等, 我们提到注册动作registerAct: 改进增加 Base62x.class....

    oujie 评论0 收藏0
  • -Base62x 新增 -Perl 版本技术实现 Base62x.pm

    摘要:同的其他版本相通,实现了跨编程语言运行时环境的数据安全交换。函数式编程的除了式的写法,还提供了函数式编程的调用方式,列如下。函数式编程适合单一次启动并运行的使用场景。 在此前的一篇Blog(-R/G2SW )中,-gMIS 吉密斯优化更新+分组项区段AddGroupBySeg/+复制AddByCopy等, 我们提到注册动作registerAct: 改进增加 Base62x.class....

    weij 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<