我有一个看起来像这样的字符串(包含数字,句号和破折号):
1372137673.276886940002-19690324617-19694854617-18953258947
由于我只有数字,句号和短划线,我想使用url-safe(仅限数字和字母)编码方案来缩短它。我还需要能够将编码的字符串反转为其原始形式。
我看了一下base64,但它增加了字符串的大小,这不是我想要的。
我打算用PHP和Javascript实现这个。
有没有现成的方案可以做到这一点?我的主要动机是缩短上面的字符串,结果应该是URL安全。
答案 0 :(得分:1)
将数字转换为二进制形式,然后Base64编码 。
答案 1 :(得分: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;
?>
答案 2 :(得分:0)
一个合理的尝试是:
但是,“必须在JS中执行此操作”的要求似乎有点怀疑 - 为什么您的客户端代码必须从最终受服务器授权的URL中提取信息?一般来说,URL应该是不透明的,当不是真的时候,警报应该响起来。
答案 3 :(得分: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;