user1246561
user1246561

Reputation:

Turning an integer into random string and back again

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

Upvotes: 6

Views: 12179

Answers (7)

lule75
lule75

Reputation: 1

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.

Upvotes: 0

Peter Porfy
Peter Porfy

Reputation: 9040

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

Upvotes: 3

Jon
Jon

Reputation: 437854

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.

Upvotes: 1

Edward Dale
Edward Dale

Reputation: 30143

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.

Upvotes: 0

Karoly Horvath
Karoly Horvath

Reputation: 96326

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.

Upvotes: 2

George
George

Reputation: 2110

The easiest way to get random string is to use hash functions like md5() or sha1() For example:

<?php
$bigInt = '131569877435989900';
$hash = md5($bigInt);
$hashed=substr($hash,0,-20);
echo $hashed;
?>

These hash functions are irreversible-you can't get the original value(these functions are also used to crypt data). If you want you can save the original big integer in an array or a database. But decripting the hash would be impossible.

Upvotes: -1

Johnatan
Johnatan

Reputation: 1268

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

$num = 131569877435989900;
echo $str = base64_encode($num);
echo base64_decode($str);

Upvotes: 0

Related Questions