1. 程式人生 > >微博URL短地址lua生成演算法

微博URL短地址lua生成演算法

短地址(Short URL),或叫短網址、短連結等等,就是比較短的URL地址。藉助短地址,可以將原來冗長的網址替換成簡短的網址,讓使用者可以更容易分享連結。在Web 2.0的今天,不得不說,這是一個潮流(我喜歡這句話,就原封不動從別人文章複製過來了)。例如:http://t.cn/pQ8LLW 短地址,主要應用場景是微博。微博訊息限制字數為140字,如果要發一些連結,這個網址可能佔用一半字數了,所以短地址就應運而生。短地址的生成演算法有很多種,這裡取其中一種做實現。無論哪種演算法都不能避免重複,所以要結合資料庫對網址和短地址做對映。結合MD5的實現演算法:1. 將網址md5後生成32位串,分4段, 每段8位元組
2. 對這四段迴圈處理,和0x3FFFFFFF與運算,即保留30位資料3. 根據字母表長度取索引值,如a-zA-Z0-9,就有62位,取0x3D (下標從0開始)4. 將前面的30位資料分成6段,每5位再和0x3D與運算,算得字母表下標,取到6位字串這種演算法,會生成4個6位字串。lua版的演算法如下:
local md5 = require "md5.core"
function md5.sumhexa(k)
	k = md5.sum(k)
	return (string.gsub(k, ".", function (c)
		return string.format("%02x", string.byte(c))
	end))
end

local SHORT_BASE = {
	"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"
}
local SHORT_PRE = "short_pre"

function short_url(str)
	local m = md5.sumhexa(SHORT_PRE..str)
	local ret = {}
	for k=0,3 do
			local sub = string.sub(m, k*8+1, k*8+8)
			local int =  0x3fffffff & tonumber(sub, 16)
			local out = ''
			for j=1,6 do
					local v = ( 0x3d & int) + 1
					out = out .. SHORT_BASE[v]
					int = int >> 5
			end
			table.insert(ret, out)
	end
	return ret
end

local ret = short_url("hello world")
for k,v in pairs(ret) do
	print("short_url", v)
end

注意了,lua比較特殊,陣列下標從1開始。結果如下:


另外,再提供可讓使用者輸入的短地址版本。就是隻保留大寫字母和數字,同時去掉了容易混淆的O0I1 。演算法類似,可做啟用碼。

local md5 = require "md5.core"
function md5.sumhexa(k)
	k = md5.sum(k)
	return (string.gsub(k, ".", function (c)
		return string.format("%02x", string.byte(c))
	end))
end

local SHORT_BASE = {
	'A','B','C','D','E','F','G','H',
	'J','K','L','M','N','P','Q','R',
	'S','T','U','V','W','X','Y','Z',
	'2','3','4','5','6','7','8','9',
}
local SHORT_PRE = "short_pre"

function short_url(str)
	local m = md5.sumhexa(SHORT_PRE..str)
	local ret = {}
	for k=0,3 do
			local sub = string.sub(m, k*8+1, k*8+8)
			local int =  0x3fffffff & tonumber(sub, 16)
			local out = ''
			for j=1,6 do
					local v = ( 0x1f & int) + 1
					out = out .. SHORT_BASE[v]
					int = int >> 5
			end
			table.insert(ret, out)
	end
	return ret
end

local ret = short_url("hello world")
for k,v in pairs(ret) do
	print("short_url", v)
end
結果如下:



參考:

http://blog.csdn.net/mycwq/article/details/52326266