ホームページ  >  記事  >  バックエンド開発  >  php创造短ID PHPで短いIDを作成 - YoutubeやTinyURLなど

php创造短ID PHPで短いIDを作成 - YoutubeやTinyURLなど

WBOY
WBOYオリジナル
2016-06-13 13:06:411097ブラウズ

php创建短ID PHPで短いIDを作成する - YoutubeやTinyURL
など

?

?

多ければ少ないほど - 「数学」

アルファベットは 26 文字です。それは10桁をはるかに超えています。大文字と小文字も区別し、その束または全体に数字を追加すると、位置ごとに (26 x 2 + 10)?62 個のオプション? を使用できるようになります。 ?ID 内にあります。

もちろん、- / * & # のような面白い文字を「束」に追加することもできますが、それらは URL で問題を引き起こす可能性があるため、現時点ではそれが私たちのターゲットです。

それでは、おおよそ?6 倍以上の文字があるので、位置ごとに使用します。ID は大幅に?短くなります各位置により多くのデータを当てはめることができます

これは基本的に tinyurl、is.gd、bit.ly などの URL 短縮サービスが行うことです。ただし、同様の ID は YouTube:?http://www.youtube.com/watch?v=yzNjIBEdyww

でも見つかります。

ID を変換します

データベース サーバーとは異なります。Web サーバーは拡張が簡単なので、データベースを数値で高速に保ちながら、ユーザーの負担を軽減するために少しの変換を実行させることができます (MySQL は単純な数値を非常に好みます ; )。

変換を行うために、大きな数値を短い文字列に、またはその逆に変換できる PHP 関数を作成しました。私はそれを alphaID と呼びます。

結果の文字列を解読するのは難しくありませんが、URL やディレクトリ構造をよりコンパクトで重要なものにするための非常に優れた機能となります。

基本的には次のとおりです。

  • 誰かが rLHWfKd をリクエストしたとき
  • alphaID() は 999999999999 に変換します
  • データベースで ID 999999999999 のレコードを検索します

?

?

出典

13fb726fa066137f635a46b8ff12426a PpQXn7COf
 *
 * specifiying the second argument true, it will
 * translate back e.g.:
 * PpQXn7COf --> 9007199254740989
 *
 * this function is based on any2dec && dec2any by
 * fragmer[at]mail[dot]ru
 * see: http://nl3.php.net/manual/en/function.base-convert.php#52450
 *
 * If you want the alphaID to be at least 3 letter long, use the
 * $pad_up = 3 argument
 *
 * In most cases this is better than totally random ID generators
 * because this can easily avoid duplicate ID's.
 * For example if you correlate the alpha ID to an auto incrementing ID
 * in your database, you're done.
 *
 * The reverse is done because it makes it slightly more cryptic,
 * but it also makes it easier to spread lots of IDs in different
 * directories on your filesystem. Example:
 * $part1 = substr($alpha_id,0,1);
 * $part2 = substr($alpha_id,1,1);
 * $part3 = substr($alpha_id,2,strlen($alpha_id));
 * $destindir = "/".$part1."/".$part2."/".$part3;
 * // by reversing, directories are more evenly spread out. The
 * // first 26 directories already occupy 26 main levels
 *
 * more info on limitation:
 * - http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/165372
 *
 * if you really need this for bigger numbers you probably have to look
 * at things like: http://theserverpages.com/php/manual/en/ref.bc.php
 * or: http://theserverpages.com/php/manual/en/ref.gmp.php
 * but I haven't really dugg into this. If you have more info on those
 * matters feel free to leave a comment.
 *
 * The following code block can be utilized by PEAR's Testing_DocTest
 * ffbe95d20f3893062224282accb13e8f
 * // Input //
 * $number_in = 2188847690240;
 * $alpha_in  = "SpQXn7Cb";
 *
 * // Execute //
 * $alpha_out  = alphaID($number_in, false, 8);
 * $number_out = alphaID($alpha_in, true, 8);
 *
 * if ($number_in != $number_out) {
 *	 echo "Conversion failure, ".$alpha_in." returns ".$number_out." instead of the ";
 *	 echo "desired: ".$number_in."\n";
 * }
 * if ($alpha_in != $alpha_out) {
 *	 echo "Conversion failure, ".$number_in." returns ".$alpha_out." instead of the ";
 *	 echo "desired: ".$alpha_in."\n";
 * }
 *
 * // Show //
 * echo $number_out." => ".$alpha_out."\n";
 * echo $alpha_in." => ".$number_out."\n";
 * echo alphaID(238328, false)." => ".alphaID(alphaID(238328, false), true)."\n";
 *
 * // expects:
 * // 2188847690240 => SpQXn7Cb
 * // SpQXn7Cb => 2188847690240
 * // aaab => 238328
 *
 * 1cd55414ff5abdfea5dd958e7e547fdd
 *
 * @author	Kevin van Zonneveld 43302df92ae238877a95badd3e2d402a
 * @author	Simon Franz
 * @author	Deadfish
 * @copyright 2008 Kevin van Zonneveld (http://kevin.vanzonneveld.net)
 * @license   http://www.opensource.org/licenses/bsd-license.php New BSD Licence
 * @version   SVN: Release: $Id: alphaID.inc.php 344 2009-06-10 17:43:59Z kevin $
 * @link	  http://kevin.vanzonneveld.net/
 *
 * @param mixed   $in	  String or long input to translate
 * @param boolean $to_num  Reverses translation when true
 * @param mixed   $pad_up  Number or boolean padds the result up to a specified length
 * @param string  $passKey Supplying a password makes it harder to calculate the original ID
 *
 * @return mixed string or long
 */
function alphaID($in, $to_num = false, $pad_up = false, $passKey = null)
{
	$index = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
	if ($passKey !== null) {
		// Although this function's purpose is to just make the
		// ID short - and not so much secure,
		// with this patch by Simon Franz (http://blog.snaky.org/)
		// you can optionally supply a password to make it harder
		// to calculate the corresponding numeric ID

		for ($n = 0; $n8d9bbae76e4e6a0c6a39f39c9a3b45b7 0) $out -= pow($base, $pad_up);
		}
		$out = sprintf('%F', $out);
		$out = substr($out, 0, strpos($out, '.'));
	} 
	else 
	{
		// Digital number  -->>  alphabet letter code
		if (is_numeric($pad_up)) {
			$pad_up--;
			if ($pad_up > 0) $in += pow($base, $pad_up);
		}

		$out = "";
		for ($t = floor(log($in, $base)); $t >= 0; $t--) {
			$bcp = bcpow($base, $t);
			$a   = floor($in / $bcp) % $base;
			$out = $out . substr($index, $a, 1);
			$in  = $in - ($a * $bcp);
		}
		$out = strrev($out); // reverse
	}

	return $out;
}

?

実行中:

alphaID<span style="color: #66cc66; padding: 0px; margin: 0px;">(</span><span style="color: #cc66cc; padding: 0px; margin: 0px;">9007199254740989</span><span style="color: #66cc66; padding: 0px; margin: 0px;">)</span>;

は「PpQXn7COf」と次の内容を返します:

alphaID<span style="color: #66cc66; padding: 0px; margin: 0px;">(</span><span style="color: #ff0000; padding: 0px; margin: 0px;">'PpQXn7COf'</span>, <span style="font-weight: 700; color: #000000; padding: 0px; margin: 0px;">true</span><span style="color: #66cc66; padding: 0px; margin: 0px;">)</span>;

は「9007199254740989

を返します

簡単ですよね?

その他の機能

  • オプションの 3 番目の引数:?$pad_up もあります。これにより、結果の alphaId を少なくとも?X? 文字長にすることができます。
  • 関数本体の先頭にある?$index?var に文字を追加すると、さらに多くの文字をサポートできます (結果の alphaID をさらに小さくできます)。

?

?

?

JavaScript の実装

Even Simon のおかげで、JavaScript が実装されました。ここには、エンコード関数とデコード関数をクラス内の別個のメソッドとして実装する PHP バージョンもあります。

3f1c4e4b6b16bbbd69b2ee476dc4f83a
/**
 *  Javascript AlphabeticID class
 *  (based on a script by Kevin van Zonneveld 43302df92ae238877a95badd3e2d402a)
 *
 *  Author: Even Simon a2017fd670625a345e7fae8d0ae62ba9
 *
 *  Description: Translates a numeric identifier into a short string and backwords.
 *
 *  Usage:
 *    var str = AlphabeticID.encode(9007199254740989); // str = 'fE2XnNGpF'
 *    var id = AlphabeticID.decode('fE2XnNGpF'); // id = 9007199254740989;
 **/
 
var AlphabeticID = {
  index:'abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ',
 
  /**
   *  dc6b9bed6e162109e509ac9db288b792@function5db79b134e9f6b82c0b36e0489ee08ed AlphabeticID.encode
   *  65dd650c1fcd4c5f0b032325ef828274@description5db79b134e9f6b82c0b36e0489ee08ed Encode a number into short string
   *  f7bd985365a21f93fd6e9a04a7355b88@param5db79b134e9f6b82c0b36e0489ee08ed integer
   *  42e20114d3d6dbd617b03983241942dc@return5db79b134e9f6b82c0b36e0489ee08ed string
   **/
  encode:function(_number){
    if('undefined' == typeof _number){
      return null;
    }
    else if('number' != typeof(_number)){
      throw new Error('Wrong parameter type');
    }
 
    var ret = '';
 
    for(var i=Math.floor(Math.log(parseInt(_number))/Math.log(AlphabeticID.index.length));i>=0;i--){
      ret = ret + AlphabeticID.index.substr((Math.floor(parseInt(_number) / AlphabeticID.bcpow(AlphabeticID.index.length, i)) % AlphabeticID.index.length),1);
    }
 
    return ret.reverse();
  },
 
  /**
   *  dc6b9bed6e162109e509ac9db288b792@function5db79b134e9f6b82c0b36e0489ee08ed AlphabeticID.decode
   *  65dd650c1fcd4c5f0b032325ef828274@description5db79b134e9f6b82c0b36e0489ee08ed Decode a short string and return number
   *  f7bd985365a21f93fd6e9a04a7355b88@param5db79b134e9f6b82c0b36e0489ee08ed string
   *  42e20114d3d6dbd617b03983241942dc@return5db79b134e9f6b82c0b36e0489ee08ed integer
   **/
  decode:function(_string){
    if('undefined' == typeof _string){
      return null;
    }
    else if('string' != typeof _string){
      throw new Error('Wrong parameter type');
    }
 
    var str = _string.reverse();
    var ret = 0;
 
    for(var i=0;i<=(str.length - 1);i++){
      ret = ret + AlphabeticID.index.indexOf(str.substr(i,1)) * (AlphabeticID.bcpow(AlphabeticID.index.length, (str.length - 1) - i));
    }
 
    return ret;
  },
 
  /**
   *  dc6b9bed6e162109e509ac9db288b792@function5db79b134e9f6b82c0b36e0489ee08ed AlphabeticID.bcpow
   *  65dd650c1fcd4c5f0b032325ef828274@description5db79b134e9f6b82c0b36e0489ee08ed Raise _a to the power _b
   *  f7bd985365a21f93fd6e9a04a7355b88@param5db79b134e9f6b82c0b36e0489ee08ed float _a
   *  f7bd985365a21f93fd6e9a04a7355b88@param5db79b134e9f6b82c0b36e0489ee08ed integer _b
   *  42e20114d3d6dbd617b03983241942dc@return5db79b134e9f6b82c0b36e0489ee08ed string
   **/
  bcpow:function(_a, _b){
    return Math.floor(Math.pow(parseFloat(_a), parseInt(_b)));
  }
};
 
/**
 *  dc6b9bed6e162109e509ac9db288b792@function5db79b134e9f6b82c0b36e0489ee08ed String.reverse
 *  65dd650c1fcd4c5f0b032325ef828274@description5db79b134e9f6b82c0b36e0489ee08ed Reverse a string
 *  42e20114d3d6dbd617b03983241942dc@return5db79b134e9f6b82c0b36e0489ee08ed string
 **/
String.prototype.reverse = function(){
  return this.split('').reverse().join('');
};
2cacc6d41bbb37262a98f745aa00fbf0

?

?

Python の実装

?wessite のおかげで、Python 実装があります。

?

ALPHABET = "bcdfghjklmnpqrstvwxyz0123456789BCDFGHJKLMNPQRSTVWXYZ"
BASE = len(ALPHABET)
MAXLEN = 6
 
def encode_id(self, n):
 
    pad = self.MAXLEN - 1
    n = int(n + pow(self.BASE, pad))
 
    s = []
    t = int(math.log(n, self.BASE))
    while True:
        bcp = int(pow(self.BASE, t))
        a = int(n / bcp) % self.BASE
        s.append(self.ALPHABET[a:a+1])
        n = n - (a * bcp)
        t -= 1
        if t 943f25ef037260f44d8832fe9e7553f2 l: break
 
    pad = self.MAXLEN - 1
    s = int(s - pow(self.BASE, pad))
 
    return int(s)

?

Python の実装

Andy Li のおかげで、HaXe が実装されました。

?
/**
 *  HaXe version of AlphabeticID
 *  Author: Andy Li dfa47c48eb53824369861ccbc8dc7c59
 *  ported from...
 *
 *  Javascript AlphabeticID class
 *  Author: Even Simon a2017fd670625a345e7fae8d0ae62ba9
 *  which is based on a script by Kevin van Zonneveld 43302df92ae238877a95badd3e2d402a)
 *
 *  Description: Translates a numeric identifier into a short string and backwords.
 *  http://kevin.vanzonneveld.net/techblog/article/create_short_ids_with_php_like_youtube_or_tinyurl/
 **/
 
class AlphaID {
    static public var index:String = 'abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
 
    static public function encode(_number:Int):String {        
        var strBuf = new StringBuf();
 
        var i = 0;
        var end = Math.floor(Math.log(_number)/Math.log(index.length));
        while(i <= end) {
            strBuf.add(index.charAt((Math.floor(_number / bcpow(index.length, i++)) % index.length)));
        }
 
        return strBuf.toString();
    }
 
    static public function decode(_string:String):Int {
        var str = reverseString(_string);
        var ret = 0;
 
        var i = 0;
        var end = str.length - 1;
        while(i <= end) {
            ret += Std.int(index.indexOf(str.charAt(i)) * (bcpow(index.length, end-i)));
            ++i;
        }
 
        return ret;
    }
 
    inline static private function bcpow(_a:Float, _b:Float):Float {
        return Math.floor(Math.pow(_a, _b));
    }
 
    inline static private function reverseString(inStr:String):String {
        var ary = inStr.split("");
        ary.reverse();
        return ary.join("");
    }
}

?

?来源: http://kevin.vanzonneveld.net/techblog/article/create_short_ids_with_php_like_youtube_or_tinyurl/

?

?

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。