文档章节

微博URL短网址生成算法原理及(java版、php版实现实例)

小老傅
 小老傅
发布于 2014/08/20 17:51
字数 1715
阅读 3915
收藏 40

短网址(Short URL),顾名思义就是在形式上比较短的网址。通常用的是asp或者php转向,在Web 2.0的今天,不得不说,这是一个潮流。目前已经有许多类似服务,借助短网址您可以用简短的网址替代原来冗长的网址,让使用者可以更容易的分享链接。 例如:http://t.cn/SzjPjA

短网址服务,可能很多朋友都已经不再陌生,现在大部分微博、手机邮件提醒等地方已经有很多应用模式了,并占据了一定的市场。估计很多朋友现在也正在使用。 看过新浪的短连接服务,发现后面主要有6个字符串组成,于是第一个想到的就是原来公司写的一个游戏激活码规则,也就是下面的算法2, 26个大写字母 26小写字母,10个数字,随机生成6个然后插入数据库对应一个id,短连接跳转的时候,根据字符串查询到对应id,即可实现相应的跳转!不过2的62次方,不知道有没有重复的,小概率可以,但是对应不是很大的网站应该足够了 自从twitter推出短网址(shorturl),继之国内各大微博跟风,google公开goo.gl使用API,短网址之风愈演愈烈.不得不说这是一个新兴又一大热门web2.0服务.现整理一下,包括完整短网址网站,短网址生成原理,算法举例,以及优劣比较,同时还介绍几个phper个人实现的。

短链接的好处:

1、内容需要;2、用户友好;3、便于管理。

为什么要这样做的,原因我想有这样几点: 微博限制字数为140字一条,那么如果我们需要发一些连接上去,但是这个连接非常的长,以至于将近要占用我们内容的一半篇幅,这肯定是不能被允许的,所以短网址应运而生了。 短网址可以在我们项目里可以很好的对开放级URL进行管理。有一部分网址可以会涵盖暴力,广告等信息,这样我们可以通过用户的举报,完全管理这个连接将不出现在我们的应用中,应为同样的URL通过加密算法之后,得到的地址是一样的。 我们可以对一系列的网址进行流量,点击等统计,挖掘出大多数用户的关注点,这样有利于我们对项目的后续工作更好的作出决策。

算法原理 算法一 1)将长网址md5生成32位签名串,分为4段, 每段8个字节; 2)对这四段循环处理, 取8个字节, 将他看成16进制串与0x3fffffff(30位1)与操作, 即超过30位的忽略处理; 3)这30位分成6段, 每5位的数字作为字母表的索引取得特定字符, 依次进行获得6位字符串; 4)总的md5串可以获得4个6位串; 取里面的任意一个就可作为这个长url的短url地址; 这种算法,虽然会生成4个,但是仍然存在重复几率,下面的算法一和三,就是这种的实现. 算法二 a-zA-Z0-9 这64位取6位组合,可产生500多亿个组合数量.把数字和字符组合做一定的映射,就可以产生唯一的字符串,如第62个组合就是aaaaa9,第63个组合就是aaaaba,再利用洗牌算法,把原字符串打乱后保存,那么对应位置的组合字符串就会是无序的组合。 把长网址存入数据库,取返回的id,找出对应的字符串,例如返回ID为1,那么对应上面的字符串组合就是bbb,同理 ID为2时,字符串组合为bba,依次类推,直至到达64种组合后才会出现重复的可能,所以如果用上面的62个字符,任意取6个字符组合成字符串的话,你的数据存量达到500多亿后才会出现重复的可能。 具体参看这里彻底完善新浪微博接口和超短URL算法,算法四可以算作是此算法的一种实现,此算法一般不会重复,但是如果是统计的话,就有很大问题,特别是对域名相关的统计,就抓瞎了。

java语言实现: Java代码 package com.test;

import java.security.MessageDigest;

public class ShortURL { private final static String[] hexDigits = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"};

	public static String byteArrayToHexString(byte[] b){
		StringBuffer resultSb = new StringBuffer();
		for (int i = 0; i < b.length; i++){
			resultSb.append(byteToHexString(b[i]));
		}
		return resultSb.toString();
	}

	private static String byteToHexString(byte b){
		int n = b;
		if (n < 0)
			n = 256 + n;
		int d1 = n / 16;
		int d2 = n % 16;
		return hexDigits[d1] + hexDigits[d2];
	}

	public static String MD5Encode(String origin){
		String resultString = null;
			try {
				
				resultString=new String(origin);
				MessageDigest md = MessageDigest.getInstance("MD5");
				
				resultString.trim();

				resultString=byteArrayToHexString(md.digest(resultString.getBytes("UTF-8")));
			}catch (Exception ex){}
			return resultString;
		}

public static void main(String[] args) { 
    String url = "http://www.bai.com"; 
    for (String string : ShortText(url)) { 
        print(string); 
    } 
} 
 
public static String[] ShortText(String string){ 
    String key = "XuLiang";                 //自定义生成MD5加密字符串前的混合KEY 
    String[] chars = new String[]{          //要使用生成URL的字符 
        "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","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" 
    }; 
     
    String hex = MD5Encode(key + string); 
    int hexLen = hex.length(); 
    int subHexLen = hexLen / 8; 
    String[] ShortStr = new String[4]; 
     
    for (int i = 0; i < subHexLen; i++) { 
        String outChars = ""; 
        int j = i + 1; 
        String subHex = hex.substring(i * 8, j * 8); 
        long idx = Long.valueOf("3FFFFFFF", 16) & Long.valueOf(subHex, 16); 
         
        for (int k = 0; k < 6; k++) { 
            int index = (int) (Long.valueOf("0000003D", 16) & idx); 
            outChars += chars[index]; 
            idx = idx >> 5; 
        } 
        ShortStr[i] = outChars; 
    } 
     
    return ShortStr; 
} 
 
public static void print(Object messagr){ 
    System.out.println(messagr); 
} 

}

以下为php语言实现: Php代码

<?php function shorturl($input) { $base32 = array ( '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', '0', '1', '2', '3', '4', '5' ); $hex = md5($input); $hexLen = strlen($hex); $subHexLen = $hexLen / 8; $output = array(); for ($i = 0; $i < $subHexLen; $i++) { $subHex = substr ($hex, $i * 8, 8); $int = 0x3FFFFFFF & (1 * ('0x'.$subHex)); $out = ''; for ($j = 0; $j < 6; $j++) { $val = 0x0000001F & $int; $out .= $base32[$val]; $int = $int >> 5; } $output[] = $out; } return $output; } ?>

Php代码

<?php function random($length, $pool = '') { $random = ''; if (emptyempty($pool)) { $pool = 'abcdefghkmnpqrstuvwxyz'; $pool .= '23456789'; } srand ((double)microtime()*1000000); for($i = 0; $i < $length; $i++) { $random .= substr($pool,(rand()%(strlen ($pool))), 1); } return $random; } ?>

跳转原理 当我们生成短链接之后,只需要在表中(数据库或者NoSql )存储原始链接与短链接的映射关系即可。当我们访问短链接时,只需要从映射关系中找到原始链接,即可跳转到原始链接。

本文转载自:http://iteye.blog.163.com/blog/static/1863080962012111223141936/

小老傅
粉丝 7
博文 44
码字总数 35819
作品 0
海淀
程序员
私信 提问
加载中

评论(5)

小帅帅丶
小帅帅丶
短链接转长链接呢?
小99
小99
循环1W次 有重复的 怎么解决
小老傅
小老傅 博主

引用来自“chuckpu”的评论

浏览器如何解析短url呢
类似于struts2框架中的action的拦截的操作,域名肯定是一个固定的(不然竞争对手拿到了你的一批短url解析以后不断的就获取了你更多的长的url了……),然后拦截到以后,进行数据库中短url和原始的url匹配操作……
chuckpu
chuckpu
浏览器如何解析短url呢
蓝浩
蓝浩
是62的6次方吧
URL短地址压缩算法 微博短地址原理解析 (Java实现)

最近,项目中需要用到短网址(ShortUrl)的算法,于是在网上搜索一番,发现有C#的算法,有.Net的算法,有PHP的算法,就是没有找到Java版的短网址(ShortUrl)的算法,很是郁闷。同时还发现有...

神勇小白鼠
2014/07/29
790
0
微博短链接的生成算法(Java版本)

微博短链接的生成算法(Java 版本) 最近看到微博的短链接真是很火啊,新浪、腾讯、搜狐等微博网站都加入了短链接的功能。之所以要是使用短链接,主要是因为微博只允许发140 字,如果链接地址太...

java-苦苦甜甜
2012/11/22
525
3
汽车之家竟然用的Discuz!???

晚上上网看汽车之家论坛(汽车论坛里访问量最大的),发现似乎用的Discuz,然后查了下JAVA版的这样开源软件,竟然没有!ASP有一款,大部分都是PHP的,Discuz是Php的,发现Discuz不是一般般的强...

wrean2013
2013/09/26
1K
12
用php来实现lucene包来实现全文检索

因为PHP本身就支持调用外部Java类,所以先用Java写了一个类, 这个类通过调用Lucene的API,实现了两个方法: public String createIndex(String indexDirpath,String dataDirpath) public S...

安安-Anan
2015/08/12
30
0
Common Gui Tools 1.2 发布,Java GUI 实用小工具集

Common Gui Tools 是用java编写,GUI界面的实用小工具集,1.2版有16个小工具: 欢迎您使用并提供宝贵意见! 下载及使用说明: Require Java 6.0+ 下载压缩包common_gui_tools-1.2.zip,解压,...

bs2004
2014/10/17
2.9K
38

没有更多内容

加载失败,请刷新页面

加载更多

手写RPC框架指北另送贴心注释代码一套

Angular8正式发布了,Java13再过几个月也要发布了,技术迭代这么快,框架的复杂度越来越大,但是原理是基本不变的。所以沉下心看清代码本质很重要,这次给大家带来的是手写RPC框架。 完整代码...

全菜工程师小辉
9分钟前
2
0
【Java】开发收货

简介 谨以此篇,记载开发过程中的一些tips。 编译器 【Shift + F6】可实现变量的联动修改。

Areya
26分钟前
5
0
DOM官方定义

DOM Document Object Model 文档对象模型 DOM的官方定义:W3C的DOM,可以使程序或者脚本(JS或AS\JScript),动态的访问或者操作文档的内容、结构、样式。 DOM只是一个标准,操作网页的标准。...

前端老手
31分钟前
6
0
IT兄弟连 HTML5教程 HTML5的学习线路图 第一阶段学习网页制作

学习HTML5技术可并不是简单学会几个新增的标签而已,HTML5现在可以说是前端所有技术的代名词。需要学习的语言和工具不仅多,对于刚接触他们的新人会感觉很乱。另外,前端开发也会细分很多个开...

老码农的一亩三分地
33分钟前
6
0
可见性有序性,Happens-before来搞定

写在前面 上一篇文章并发 Bug 之源有三,请睁大眼睛看清它们 谈到了可见性/原子性/有序性三个问题,这些问题通常违背我们的直觉和思考模式,也就导致了很多并发 Bug 为了解决 CPU,内存,IO ...

tan日拱一兵
48分钟前
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部