2

How can I convert an Ipv4 and Port to a 5 char identifier in PHP?

For example,

localhost/127.0.0.1:80

To this:

localhost/#12345 //#12345 is the 127.0.0.1:80

Is this possible to do in PHP? And how?

bobi
  • 61
  • 1
  • 9
  • There is not obvious out-of-the-box way, so you had better add a lilttle more description about what you are trying to achieve so we can suggest a way to do it – RiggsFolly Apr 29 '16 at 14:46
  • @RiggsFolly I don't want the whole ip showing up on the address bar and i also want to hide it. – bobi Apr 29 '16 at 14:47
  • It seems to me you want a displayable IP address? That is bad form, and discloses personal information about the visitors. Even obfuscated you are providing a way for smart people to figure this out. At the end of the day this is binary data (4 8 bit bytes per octet) + a 16 bit port range. There is no way of doing this in 5 characters, unless what you really mean is you want something like what @mister-martin is proposing. – gview Apr 29 '16 at 16:00

3 Answers3

1

I believe what you're actually after is not a converter, but a URL shortener. If that's the case, I highly recommend watching this video which explains how YouTube creates their unique IDs. Basically, they use a completely random base64 number that is 11 characters long, comprised of the characters 0-9, A-Z, a-z, - and _. To give you an idea how many different combinations this allows based on the number of characters you're using:

  1. 64 combinations
  2. (64x64) = 4096 combinations
  3. (64x64x64) = 262144 combinations
  4. (64x64x64x64) = 16777216 combinations
  5. (64x64x64x64x64) = 1073741824 combinations

So the basic idea is generate a random number, make sure the number doesn't already exist in your database, then store the number which you can associate with your IP address (or whatever else you want). The following code is provided as an example of how to create such a number.

// get random text
// default charset base64: +/A-Za-z0-9
// $len: desired length
// $chars: optional string of characters to use
function randText($len, $chars = null) {
    if ($len < 1) {
        return false;
    }

    if (!isset($chars)) {
        // base64 result is about 33% longer than input
        $num_bytes = ceil($len * 0.75);
        $bytes = randBytes($num_bytes);
        return substr(rtrim(base64_encode($bytes), '='), 0, $len);
    }

    $char_len = strlen($chars);
    if ($char_len == 1) {
        return str_repeat($chars, $len);
    }

    $bytes = randBytes($len);
    $pos = 0;
    $result = '';
    for ($i = 0; $i < $len; $i++) {
        $pos = ($pos + ord($bytes[$i])) % $char_len;
        $result .= $chars[$pos];
    }

    return $result;
}

// to be used in conjunction with randText()
function randBytes($len) {
    $result = '';
    if (extension_loaded('openssl')) {
        $result = openssl_random_pseudo_bytes($len, $strong);
        if ($strong === true) {
            return $result;
        }
    }

    // fallback, more predictable
    for ($i = 0; $i < $len; $i++) {
        $result .= chr(mt_rand(0, 255));
    }

    return $result;
}

With these two functions, we can now grab a unique ID (with the appropriate URL-safe characters) and store it:

$chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_';
$shortcode = randText(5, $chars);

// pseudo code
if (already_exists($shortcode)) {
    // get a new shortcode
} else {
    update_database($shortcode, '127.0.0.1:80');
}

Now when someone accesses a URL on your site you can grab the unique identifier, find the IP in your database, and handle the request accordingly through URL rewriting and/or some type of Front Controller pattern.

Community
  • 1
  • 1
mister martin
  • 6,197
  • 4
  • 30
  • 63
0

I don't think it's possible with only 5 characters. Consider that you want "safe" characters only in the URL, which are alphanumeric and a few other ones like underscore. At most there are 84 such characters (I can't find an authoritative answer). But each IP number can go from 0-255. And there are thousands of possible ports. With at most five chars, you cannot represent all possible IP/port combinations.

To "obfuscate" the IP you may take it as a string and pass it through an encoding function, though a determined user will be able to decode it. Consider the builtins

$str = '127.0.0.1:8000';

$encoded = urlencode(base64_encode($str));
$decoded = base64_decode(urldecode($encoded));

Seen In this answer

Or you may use your encoding scheme.

Community
  • 1
  • 1
Tina Vall
  • 172
  • 3
  • 11
0

5 characters (8 bits per char) are 32+8 bits ipV4 are 32 bits, so you can convert the ip, but not the port (you're stuck with a range of 255 ports given a base suited for you)

ROLO
  • 581
  • 4
  • 13
  • Unless the characters are ascii you can't display them. Although you are right about ports potentially being beyond the range of a single byte, there is no way to do this in 5 characters. – gview Apr 29 '16 at 15:57