2013-06-25 41 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;