Turning an integer into random string and back aga

2020-06-18 04:07发布

what I'm wanting is to convert an integer into a string. For example, 123456789 may become 8GFsah93r ... you know like Youtube, Pastebin and what not. I then want to convert it back.

I'm working with large integers, for example: 131569877435989900

Take a look at this link: http://codepad.viper-7.com/wHKOMi

This is my attempt using a function I found on the web, obviously... it's not correctly converting back to integer. I'm needing something that does this realiably.

Thanks

标签: php
7条回答
Luminary・发光体
2楼-- · 2020-06-18 04:21

I think what you want is to encode the ids using Base32. The resulting string contains only the 26 letters of the alphabet and the digits 2-7, making it very human readable.

查看更多
Deceive 欺骗
3楼-- · 2020-06-18 04:24

The simplest would be to use something like base_convert -- unfortunately, it won't work for such large integers correctly.

However, you can use the same idea by copying base_convert_arbitrary from my answer here and doing:

$id = '131569877435989900';
$encoded = base_convert_arbitrary($id, 10, 36);
$decoded = base_convert_arbitrary($encoded, 36, 10);

print_r($encoded);
print_r($decoded);

See it in action.

The nice thing about this approach is that you can tweak the first line inside the function, which reads:

$digits = '0123456789abcdefghijklmnopqrstuvwxyz'; // 36 "digits"

Add any other "digits" you find acceptable (e.g. capital letters or other symbols you don't mind having in your URL). You can then replace the base 36 in the above example with a larger one (you can go as high as there are defined digits), and it will work just like you want it to.

See it here working with 62 digits.

查看更多
甜甜的少女心
4楼-- · 2020-06-18 04:24

I am suprised No one is mentioning base64_encode() and it partner base64_decode().
If you were not considering length this is perfect

$before = base64_encode(131569877435989900);

$after = 'MS4zMTU2OTg3NzQzNTk5RSsxNw==';

$on_reverse = base64_decode('MS4zMTU2OTg3NzQzNTk5RSsxNw==');
$on_reverse == 131569877435989900;

I always go for the simplest solutions, as long as they don't compromise my security.

查看更多
beautiful°
5楼-- · 2020-06-18 04:25

check base64 encoding: http://php.net/manual/en/function.base64-encode.php http://php.net/manual/en/function.base64-decode.php

If you want a shorter string first encode it into an 8bit string then encode. You can do this with % 256 and / 256.

Or you could manually do what base64 does, get the first 6bits and encode it to a char.

查看更多
别忘想泡老子
6楼-- · 2020-06-18 04:26

Why not use something like this? Do you need it heavily encrypted?

$num = 131569877435989900;
echo $str = base64_encode($num);
echo base64_decode($str);
查看更多
狗以群分
7楼-- · 2020-06-18 04:27

Ok, one of the ideas is to use a character array as a representation of a numeric system. Then you can convert from base 10 to base x and vica-versa. The value will be shorter and less readable (altought, you should encrypt it with a two-way crypter if it must be secure).

A solution:

final class UrlShortener {

    private static $charfeed = Array(
    'a','A','b','B','c','C','d','D','e','E','f','F','g','G','h','H','i','I','j','J','k','K','l','L','m',
    'M','n','N','o','O','p','P','q','Q','r','R','s','S','t','T','u','U','v','V','w','W','x','X','y','Y',
    'z','Z','0','1','2','3','4','5','6','7','8','9');

    public static function intToShort($number) {
        $need = count(self::$charfeed);
        $s = '';

        do {
            $s .= self::$charfeed[$number%$need];
            $number = floor($number/$need);
        } while($number > 0);

        return $s;
    }

    public static function shortToInt($string) {
        $num = 0;
        $need = count(self::$charfeed);
        $length = strlen($string);

        for($x = 0; $x < $length; $x++) {
            $key = array_search($string[$x], self::$charfeed);
            $value = $key * pow($need, $x);
            $num += $value;
        }

        return $num;
    }
}

Then you can use:

UrlShortener::intToShort(2);
UrlShortener::shortToInt("b"); 

EDIT

with large numbers, it does not work. You should use this version (with bcmath http://www.php.net/manual/en/book.bc.php ) with very large numbers:

final class UrlShortener {

    private static $charfeed = Array(
    'a','A','b','B','c','C','d','D','e','E','f','F','g','G','h','H','i','I','j','J','k','K','l','L','m',
    'M','n','N','o','O','p','P','q','Q','r','R','s','S','t','T','u','U','v','V','w','W','x','X','y','Y',
    'z','Z','0','1','2','3','4','5','6','7','8','9');

    public static function intToShort($number) {
        $need = count(self::$charfeed);
        $s = '';

        do {
            $s .= self::$charfeed[bcmod($number, $need)];
            $number = floor($number/$need);
        } while($number > 0);

        return $s;
    }

    public static function shortToInt($string) {
        $num = 0;
        $need = count(self::$charfeed);
        $length = strlen($string);

        for($x = 0; $x < $length; $x++) {
            $key = array_search($string[$x], self::$charfeed);
            $value = $key * bcpow($need, $x);
            $num += $value;
        }

        return $num;
    }
}
$original = 131569877435989900;
$short = UrlShortener::intToShort($original);
echo $short;
echo '<br/>';
$result = UrlShortener::shortToInt($short);
echo $result;
echo '<br/>';
echo bccomp($original, $result);

If something missing from here, please let me know, because it's only a snippet from my library (I don't wanna insert the whole thing here)

negra

查看更多
登录 后发表回答