2011-07-19 14 views
5

私は自分のURLをtinyurlと同じように短くしたい、または他のURL短縮サービスにしたいと思います。URLを短縮するためのPHP base_convert

localhost/test/link.php?id=1000001 
localhost/test/link.php?id=1000002 

など

上記のリンクでのIDは、DBから行の自動インクリメントIDがある:私は、リンクの次のタイプがあります。 上記のリンクは次のようにマッピングされます。代わりに、上記の長いIDを使用しての、私はそれらを短くしたい今

localhost/test/1000001 
localhost/test/1000002 

。私はbase_convert()機能を使用できることを発見しました。それはかなり良いように見えますが、私は任意の欠点(例えば、パフォーマンスの低下やその他が。)があればお願いしたいと思います。この機能を使用するか、同じことを行うために任意のより良い方法がある

print base_convert(100000000, 10, 36); 

//output will be "1njchs" 

(例:たとえば、ランダムなID文字列を生成する独自の関数を作る)?

ありがとうございました。

答えて

4

関数base_convertは十分速いですが、もっとうまくやりたいのであれば、エンコードされた文字列をデータベースに格納してください。 base_convert()

+1

返信いただきありがとうございます。ちょうど別の(関連する)質問があります。 base_convert 'base_convert(100000000、10、36);'で数値を変換すると、関数内の基数の順序を変更することで元の数に戻すことはできますか? 'base_convert(100000000、36、10);'。 – Roman

+1

はい、確かに 'base_convert( '1njchs'、36、10)== '100000000'です。 – Gedrox

3

あなたは短いコード に文字列を変換することができ、その後、intval()で、データベースに

マイコードスニペットストアアイテムのIDを作成します - 残念ながら

$code = base_convert("long string", 10, 36); 
$ID= intval($code ,36); 
0

を、私が不満でしたここと他の回答はbase_convert()と他の浮動小数点ベースの変換方法では、暗号化の目的で容認できないほどの精度が失われます。さらに、これらの実装のほとんどは、暗号化アプリケーションに十分な数の数字を扱うことができません。以下は、大規模な基盤に対して安全であるべき基底変換の2つの方法を提供する。たとえば、base256(バイナリ文字列)をbase85表現に変換して元に戻します。 >六角2回、不要なだけでなく、base62に限定されている - あなたはビン<変換の費用でこれを達成するためにGMPを使用することができますGMP

使用

<?php 
// Not bits, bytes. 
$data = openssl_random_pseudo_bytes(256); 

$base62 = gmp_strval(gmp_init(bin2hex($data), 16), 62); 
$decoded = hex2bin(gmp_strval(gmp_init($base62, 62), 16)); 

var_dump(strcmp($decoded, $data) === 0); // true 

ピュアPHP

あなたがbase85やわずかなパフォーマンスの向上にbase62越えて移動したい場合、あなたは次のようなものが必要になります。

<?php 

/** 
* Divide a large number represented as a binary string in the specified base 
* and return the remainder. 
* 
* @param string &$binary 
* @param int $base 
* @param int $start 
*/ 
function divmod(&$binary, $base, $divisor, $start = 0) 
{ 
    /** @var int $size */ 
    $size = strlen($binary); 

    // Do long division from most to least significant byte, keep remainder. 
    $remainder = 0; 
    for ($i = $start; $i < $size; $i++) { 
     // Get the byte value, 0-255 inclusive. 
     $digit = ord($binary[$i]); 

     // Shift the remainder left by base N bits, append the last byte. 
     $temp = ($remainder * $base) + $digit; 

     // Calculate the value for the current byte. 
     $binary[$i] = chr($temp/$divisor); 

     // Carry the remainder to the next byte. 
     $remainder = $temp % $divisor; 
    } 

    return $remainder; 
} 

/** 
* Produce a base62 encoded string from a large binary number. 
* 
* @param string $binary 
* return string 
*/ 
function encodeBase62($binary) 
{ 
    $charMap = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; 
    $base = strlen($charMap); 

    $size = strlen($binary); 
    $start = $size - strlen(ltrim($binary, "\0")); 

    $encoded = ""; 
    for ($i = $start; $i < $size;) { 
     // Do long division from most to least significant byte, keep remainder. 
     $idx = divmod($binary, 256, $base, $i); 

     $encoded = $charMap[$idx] . $encoded; 

     if (ord($binary[$i]) == 0) { 
      $i++; // Skip leading zeros produced by the long division. 
     } 
    } 

    $encoded = str_pad($encoded, $start, "0", STR_PAD_LEFT); 

    return $encoded; 
} 

/** 
* Produce a large binary number from a base62 encoded string. 
* 
* @param string $ascii 
* return string 
*/ 
function decodeBase62($ascii) 
{ 
    $charMap = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; 
    $base = strlen($charMap); 

    $size = strlen($ascii); 
    $start = $size - strlen(ltrim($ascii, "0")); 

    // Convert the ascii representation to binary string. 
    $binary = ""; 
    for ($i = $start; $i < $size; $i++) { 
     $byte = strpos($charMap, $ascii[$i]); 
     if ($byte === false) { 
      throw new OutOfBoundsException("Invlaid encoding at offset '{$ascii[$i]}'"); 
     } 

     $binary .= chr($byte); 
    } 

    $decode = ""; 
    for ($i = 0; $i < $size;) { 
     // Do long division from most to least significant byte, keep remainder. 
     $idx = divmod($binary, $base, 256, $i); 

     $decode = chr($idx) . $decode; 

     if (ord($binary[$i]) == 0) { 
      $i++; // Skip leading zeros produced by the long division. 
     } 
    } 

    $decode = ltrim($decode, "\0"); 
    $decode = str_pad($decode, $start, "\0", STR_PAD_LEFT); 

    return $decode; 
} 

// Not bits, bytes. 
$data = openssl_random_pseudo_bytes(256); 

$base62 = encodeBase62($data); 
$decoded = decodeBase62($base62); 

var_dump(strcmp($decoded, $data) === 0); // true 
関連する問題