欢迎关注Hadoop、Spark、Flink、Hive、Hbase、Flume等大数据资料分享微信公共账号:iteblog_hadoop
  1. 文章总数:960
  2. 浏览总数:11,449,060
  3. 评论:3870
  4. 分类目录:102 个
  5. 注册用户数:5828
  6. 最后更新:2018年10月13日
过往记忆博客公众号iteblog_hadoop
欢迎关注微信公众号:
iteblog_hadoop
大数据技术博客公众号bigdata_ai
大数据猿:
bigdata_ai

短URL实现

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 ownprivate 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 canchange 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];

转载至国外的网站

本博客文章除特别声明,全部都是原创!
转载本文请加上:转载自过往记忆(https://www.iteblog.com/)
本文链接: 【短URL实现】(https://www.iteblog.com/archives/257.html)
喜欢 (1)
分享 (0)
发表我的评论
取消评论

表情
本博客评论系统带有自动识别垃圾评论功能,请写一些有意义的评论,谢谢!