2013-06-25 86 views
0

我有一個看起來像這樣(包含數字,句號和破折號)的字符串:編碼方案來縮短數字的字符串,它是URL安全

1372137673.276886940002-19690324617-19694854617-18953258947 

因爲我只有數字,句號和破折號,我想使用url安全(僅數字和字母)編碼方案來縮短它。我還需要能夠將編碼的字符串轉換爲其原始格式。

我看了一下base64,但它增加了一個公平的字符串的大小,這不是我想要的。

我打算在PHP和Javascript中實現這個。

有沒有現有的方案可以做到這一點?我的主要動機是縮短上面的字符串,結果應該是URL安全的。

+0

你可以嘗試用urlencode()和解碼urldecode() – ripa

+0

你有12個符號編碼(10個數字,短劃線和點)和至少36個可用符號(24個字母,10個數字,短劃線和下劃線)。 **您是否嘗試過使用簡單的地圖(如base64)? –

+0

如果你可以用像'd2rdbt.hfinz2tv-8y84nrx-8y93j9s-8fhkua4'這樣的字符串,那麼我認爲可以提供幫助。因爲代碼有點大 – bystwn22

回答

1

將數字轉換爲二進制形式,然後Base64編碼

0

要做到這一點在JavaScript也,你需要的http://phpjs.org/ :)
幫助,我想我此腳本中使用的所有PHP函數可用在那裏,就像bcomp
你可以調整這個代碼來獲得一個更小的字符串,現在有點忙,如果我有時間,我一定會更新這個答案:)

<?php 
    /** 
    * This function will encode a larger number to small string 
    **/ 
    function encode($int = null) { 
    $chars = 'kwn7uh2qifbj8te9vp64zxcmayrg50ds31'; 
    $uid = ''; 
    while(bccomp($int, 0, 0) != 0) { 
     $rem = bcmod($int, 34); 
     $int = bcdiv(bcsub($int, $rem, 0), 34, 0); 
     $uid = $chars[$rem].$uid; 
    } 
    return $uid; 
    } 
    /** 
    * This function will decode a string encoded with above function to its original state 
    **/ 
    function decode($uid = null) { 
    $chars = 'kwn7uh2qifbj8te9vp64zxcmayrg50ds31'; 
    $id = ''; 
    $len = strlen($uid); 
    for($i = $len - 1; $i >= 0; $i--) { 
     $value = strpos($chars, $uid[$i]); 
     $id  = bcadd($id, bcmul($value, bcpow(34, ($len - $i - 1)))); 
    } 
    return $id; 
    } 
    /** 
    * Below function is only for your needs 
    **/ 
    function int_to_str($str = null, $decode = false) { 
    //$len = array(); // reserved for further updates :) 
    $numbers1 = explode("-", $str); 
    foreach($numbers1 as &$num1) { 
     $func = ($decode) ? "decode" : "encode"; 
     $num1 = implode(".", array_map($func, explode(".", $num1))); 
    } 
    $numbers1 = implode("-", $numbers1); 
    return $numbers1; 
    } 

    // Encode your numbers to short strings 
    $str = int_to_str("1372137673.276886940002-19690324617-19694854617-18953258947"); 
    // Decode your encoded string to its original state 
    $int = int_to_str($str, true); 

    echo $str."<br />"; 
    echo $int; 
?> 
0

一個合理的嘗試是:

  • 打破串入用破折號和點分隔的令牌
  • 將每個令牌轉換爲更高的基礎(36是可以輕鬆地從JS和PHP轉換爲基礎的基礎)
  • 將令牌加回到一起 - 破折號和圓點都是在URL中有效

但是,「必須在JS中執行此操作」的要求似乎有點可疑 - 爲什麼客戶端代碼必須從最終在服務器權限下的URL提取信息?一般來說,網址應該是不透明的,如果不是真的,警鈴應該開始響起。

0

只因爲它是好玩的事......它編碼一個自定義的基本字符串64保持完好分隔:

function encode_token($digit) { 
    if ($digit < 10) 
     return (string) $digit; 
    if ($digit < 36) 
     return chr(ord('A') + ($digit - 10)); 
    if ($digit < 62) 
     return chr(ord('a') + ($digit - 36)); 
    if ($digit == 62) return ','; 
    return '+'; 
} 

function encode_value($value) { 
    if (in_array($value, array('.', '-'))) return $value; 
    $int = (int) $value; 

    $encoded = ''; 
    while($int) { 
     $encoded .= encode_token($int & 0x3F); 
     $int >>= 6; 
    } 
    return $encoded; 
} 

function encode($string) { 
    $values = preg_split(',([\.-]),', $string, -1, PREG_SPLIT_DELIM_CAPTURE); 
    $encoded = ''; 
    foreach($values as $value) 
     $encoded .= encode_value($value); 
    return $encoded; 
} 

function decode_token($token) { 
    if ($token <= '9') return (int) $token; 
    if ($token <= 'Z') return 10 + ord($token) - ord('A'); 
    if ($token <= 'z') return 36 + ord($token) - ord('a'); 
    if ($token == ',') return 62; 
    return 63; 
} 

function decode_value($value) { 
    if (in_array($value, array('.', '-'))) return $value; 

    $decoded = 0; 
    for($i = strlen($value) - 1;$i >= 0;$i--) { 
     $decoded <<= 6; 
     $decoded |= decode_token($value[$i]); 
    } 
    return $decoded; 
} 

function decode($string) { 
    $values = preg_split(',([\.-]),', $string, -1, PREG_SPLIT_DELIM_CAPTURE); 
    $decoded = ''; 
    foreach($values as $value) 
     $decoded .= decode_value($value); 
    return $decoded; 
} 

$string = '1372137673.276886940002-19690324617-19694854617-18953258947'; 
echo $string . PHP_EOL; 
$encoded = encode($string); 
echo $encoded . PHP_EOL; 
$decoded = decode($encoded); 
echo $decoded . PHP_EOL;