摘要:短網址實作二-演算法
IF EXISTS (SELECT NAME FROM sys.objects WHERE NAME = 'NGIS_FUN_MD5' AND TYPE IN (N'FN', N'IF', N'TF', N'FS', N'FT'))
--IF OBJECT_ID(N'NGIS_GetURLKey', N'FN') IS NOT NULL
DROP FUNCTION dbo.NGIS_FUN_MD5
GO
CREATE FUNCTION dbo.NGIS_FUN_MD5 (@P_cURL nchar(2500))
RETURNS @TMP_MD5 TABLE (
iCOUNT int,
cCODE char(8)
)
--WITH ENCRYPTION
-- =============================================
--用途 : 產生短網址的演算法
--傳入值 : 原始網址
--傳出值 : 四組短網址
--版次 : 2012/6/13 Renee Modify
--
--
-- =============================================
AS BEGIN
DECLARE @P_cMD5 char(34),
@P_iN int,
@P_iP int,
@P_cTMPString char(8),
@P_iTMPInt bigint,
@P_iINDEX bigint,
@P_cOutCHAR char(8)
SELECT @P_cMD5=SYS.FN_SQLVARBASETOSTR(HashBytes('MD5', RTRIM(@P_cURL)));
/*
演算法說明
1. 將長網址用md5演算法生成32位簽名串,分為4段,,每段8個字元。
2. 對這4段循環處理,取每段的8個字元, 將他看成16進位字元串與0x3fffffff(30位1)的位移操作,超過30位的忽略處理。
3. 將每段得到的值又分成6段,得到其在字元數組中的索引並取出拼串。
4. 這樣一個md5字元串可以獲得4個6位串,取里面的任意一個就可作為這個長url的短url地址。
*/
SELECT @P_iN=0
WHILE (@P_iN<4) BEGIN
--把加密字元按照 8 位一組 16 進位與 0x3FFFFFFF 進行位與運算
SELECT @P_cTMPString=SUBSTRING(@P_cMD5,@P_iN*8+3,8);
SELECT @P_iTMPInt=CONVERT(bigint,CONVERT(varbinary(100),'0x3FFFFFFF'+@P_cTMPString)) ;
SET @P_cOutCHAR='';
--循環獲得每組6位的字元串
SELECT @P_iP=0
WHILE (@P_iP<6) BEGIN
SELECT @P_iINDEX=@P_iTMPInt%62;
SELECT @P_cOutCHAR=RTRIM(@P_cOutCHAR)+cCODE FROM SHORTER_ARRAY WHERE iINDEX=@P_iINDEX;
SELECT @P_iTMPInt=@P_iTMPInt/(POWER(2,5)); --等同右移5位 @P_iTMPInt1>>5
SET @P_iP=@P_iP+1;
END
INSERT INTO @TMP_MD5 SELECT @P_iN,@P_cOutCHAR;
SET @P_iN=@P_iN+1;
END
RETURN
END