-3

I am in need of a function to increase "LETTER/NUMBER" for each input to the database. Just like the AI for INT data.

I need this to make a shortlink code, like site.com/1gHrT.

Any ideas how to make this?

Jackie Honson
  • 1,419
  • 3
  • 13
  • 12

4 Answers4

1

URL shorteners often use big integers in base62.

Integers are normally in base10 (which is another word for the decimal system, i.e. [0-9]). There are other common systems, such as base2 ([0-1]), base8 ([0-8]) and base16 ([0-f]).

When you go above base10 it is customary to use the English lowercase alphabet ([a-z]). So, base16 is [0-9a-f] (0123456789abcdef). If you push the base beyond what digits and lowercase letters can handle then you usually use uppercase letters ([A-Z]). So, base62 uses [0-9a-zA-Z].

In PHP the base_convert() function can handle anything from base2 to base36 (or [0-1] to [0-9a-z]).

If you want to go beyond base36 then you need the gmp extension which can handle anything up to base62. If you do not have the gmp extension installed then you should be able to find a function somewhere on the interwebs. Also, while the base64_encode() function might sound relevant, in this case it is not. It encodes data, which is not the same as changing the base (or radix).

You need to keep in mind, though, that base62 can be a little fragile on the web. This is because lowercase and uppercase letters both have significance. In other words, if some bright guy or gal prefers lowercase URIs, and converts it to lowercase, then the URI will point to the wrong place. In this sense base36 is much safer, but the URI will not be as short (although not by that much).

Now, if you want to increment the number in your post then it is just a matter of converting it to base10, increment it, and then convert it back.

If we assume that it is, indeed, in base62, then we can use the gmp functions:

function base62_increment($number, $incrBy = 1) {
    if ( ! defined('GMP_VERSION'))
        throw new \Exception(__FUNCTION__.' needs the GMP extension');
    $number = gmp_init($number, 62);
    $number = gmp_add($number, $incrBy);
    return gmp_strval($number, 62);
}
$base62 = '1gHrT';
$incremented = base62_increment($base62);
var_dump($base62, $incremented);

If you want to use base36, or if you do not have the gmp extension installed, then then we can use base_convert():

function base36_increment($number, $incrBy = 1) {
    $number = base_convert($number, 36, 10);
    $number += $incrBy;
    return base_convert($number, 10, 36);
}
$base36 = 'esq2f';
$incremented = base36_increment($base36);
var_dump($base36, $incremented);

That is about it.

Community
  • 1
  • 1
Sverri M. Olsen
  • 13,055
  • 3
  • 36
  • 52
0

Maybe you're after something like?

function randLetter()
{
return chr(97 + mt_rand(0, 25));
}

Source: http://maymay.net/blog/2004/12/19/generating-random-letters-in-php/

chriz
  • 1,580
  • 19
  • 27
0

You could convert a number to an string with the given chars like you convert a number in one system to another system with something like the following algo

$n = 123; //your number

$chars = "abcdefghijklmnopqrstuvwxyz";
$chars = "0123456789" . strtoupper($chars) . $chars;
$b = strlen($chars);
$nums = array();
while ($n > 0) {
    $nums[] = $n % $b;
    $n = (int)($n / $b);
}

$nums = array_reverse($nums);
$out = "";
foreach ($nums as $num) {
    $out .= $chars[$num];
}

internally you can use a numeric counter and the output is generated with this algo..

Philipp
  • 15,377
  • 4
  • 35
  • 52
0

Untested and could probably be optimized to avoid conversions, but this converts numbers to digits but this converts sequential ints to strings.

$startval = 12435;
$maxval = 12654;

for ($i = $startval; $i < maxval; $i++) {
    $strINT = strval($i); // convert int to string
    // intialize final string to empty
    $strOutput = '';
    /* Loop through each letter */
    foreach (explode($strINT) as $letter) {
        // add 65 to each letter and turn it into a letter
        // letter A is character 65
        $strOutput .= chr(intval($letter) + 65);
    }
}
MC Emperor
  • 22,334
  • 15
  • 80
  • 130
Youn Elan
  • 2,379
  • 3
  • 23
  • 32