免費論壇 繁體 | 簡體
Sclub交友聊天~加入聊天室當版主
分享
返回列表 回復 發帖

短網址

參考網址


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
----------------------------------------------------------------------------------------

參考網址

public static string[] ShortUrl(string url)
        {
            //可以自定义生成MD5加密字符传前的混合KEY
            string key = "Leejor";
            //要使用生成URL的字符
            string[] chars = new string[]{
                "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"

              };
            //对传入网址进行MD5加密
            string hex = System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(key + url, "md5");

            string[] resUrl = new string[4];

            for (int i = 0; i < 4; i++)
            {
                //把加密字符按照8位一组16进制与0x3FFFFFFF进行位与运算
                int hexint = 0x3FFFFFFF & Convert.ToInt32("0x" + hex.Substring(i * 8, 8), 16);
                string outChars = string.Empty;
                for (int j = 0; j < 6; j++)
                {
                    //把得到的值与0x0000003D进行位与运算,取得字符数组chars索引
                    int index = 0x0000003D & hexint;
                    //把取得的字符相加
                    outChars += chars[index];
                    //每次循环按位右移5位
                    hexint = hexint >> 5;
                }
                //把字符串存入对应索引的输出数组
                resUrl = outChars;
            }

            return resUrl;
        }

现在可以直接使用该方法,可以等到下面四组值

ShortUrl(http://www.me3.cn")[0];  //得到值fAVfui

ShortUrl("http://www.me3.cn")[1];  //得到值3ayQry

ShortUrl("http://www.me3.cn")[2];  //得到值UZzyUr

ShortUrl("http://www.me3.cn")[3];  //得到值36rQZn

---------------------------------------------------------------------------
參考網址

public static string[] ShortUrl(string url)

{
         //可以自定义生成MD5加密字符传前的混合KEY
         string key = "JianYun";
         //要使用生成URL的字符
         string[] chars = new string[]{
             "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"
           };
         //对传入网址进行MD5加密
         string hex = GetMD5Hash(key + url);
   
         string[] resUrl = new string[4];
   
         for (int i = 0; i < 4; i++)
         {
             //把加密字符按照8位一组16进制与0x3FFFFFFF进行位与运算
             int hexint = 0x3FFFFFFF & Convert.ToInt32("0x" + hex.Substring(i * 8, 8), 16);
             string outChars = string.Empty;
             for (int j = 0; j < 6; j++)                  
            {                     
                //把得到的值与0x0000003D进行位与运算,取得字符数组chars索引
                int index = 0x0000003D & hexint;
                //把取得的字符相加
                outChars += chars[index];
                //每次循环按位右移5位
                hexint = hexint >> 5;
             }
             //把字符串存入对应索引的输出数组
             resUrl = outChars;
         }

         return resUrl;
}
   
public static string GetMD5Hash(string str)
{
         MD5 md5Hasher = MD5.Create();
         byte[] data = md5Hasher.ComputeHash(Encoding.Default.GetBytes(str));
         StringBuilder sBuilder = new StringBuilder();
         for (int i = 0; i < data.Length; i++)
         {
             sBuilder.Append(data.ToString("x2"));
         }
         return sBuilder.ToString();
}

------------------------------------------------------------------------------------
參考資料



10Apr/090

PHP: Short URL Algorithm Implementation

ADVERTISEMENTS
  

Few months ago, I introduced a simple algorithm that allow users to implement their own short URL into their system. Today, I have some spare time so I decided to write the short URL algorithm's implementation in PHP.

At first, we define a function called shorturl() that receives a URL as the input and returns an array that contains 4 hashed values (each 6 characters).
function shorturl($input) {
   ...
  // return array of results
}





Below is the original pseudocode:
...
  loop2: from 1st 4 bytes to 4th 4 bytes of md5 result
    cast the 4 bytes to an integer
    loop3: for shortCodeChar[0] to shortCodeChar[5]
      use 1st 5 bits of the integer to find the value in codeMap
      remove 5 bits from the integer
    end loop3
    save shortCodeChar as shortCode
    ...
    // Database checking for duplication
  end loop2
...


The following code is written according to the algorithm above excluding the database checking part for duplication:
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;
}

Sample code to test/use the above function:
$input = 'http://www.snippetit.com/1';
$output = shorturl($input);

echo "Input  : $input\n";
echo "Output : {$output[0]}\n";
echo "         {$output[1]}\n";
echo "         {$output[2]}\n";
echo "         {$output[3]}\n";
echo "\n";

$input = 'http://www.snippetit.com/2';
$output = shorturl($input);

echo "Input  : $input\n";
echo "Output : {$output[0]}\n";
echo "         {$output[1]}\n";
echo "         {$output[2]}\n";
echo "         {$output[3]}\n";
echo "\n";


Output:
Input  : http://www.snippetit.com/1
Output : h0xg4r
         bdr3tw
         osk2d3
         4azfqa

Input  : http://www.snippetit.com/2
Output : tm5kxb
         ceoj2s
         yw3dvl
         nrmrxl


The function return an array of 4 elements, you can use any one of them. The others can be used as alternative unique code for the input when you found a duplicated code in your database (same code but different input - although it is unlikely to happen but it will happen). Chances to get a duplicated code is about n/(32^6) or n/1,073,741,824 where n is the number of records in your database.

As you can see, the output results are quite random although you only have one character different in the input string. The output is always consistent, for the same input you will always get the same output.

To make the output more unpredictable by the others, you can scramble the values in the $base32 array or/and add in your own private key or/and XOR the value of $val with a value from range 0 to 31.

For example to scramble the values in the $base32 array, you can change the position of the values or/and replace the value with another (make sure the replaced value is URL safe character).

For example to add in private key, you can add in additional string when calling the md5() function, e.g.:
$hex = md5('my-secret-key'.$input.'my-another-secret-key');

For example to XOR the value of $val with value of 18:
$out .= $base32[$val ^ 18];
返回列表