tags:

views:

38

answers:

4

I am looking to create an auto incrementing unique string using PHP, containing [a-Z 0-9] starting at 2 chars long and growing when needed.

This is for a url shrinker so each string (or alias) will be saved in the database attached to a url.

Any insight would be greatly appreciated!

+2  A: 

Note this solution won't produce uppercase letters.

Use base_convert() to convert to base 36, which will use [a-z0-9].

<?php
// outputs a, b, c, ..., 2o, 2p, 2q
for ($i = 10; $i < 99; ++$i)
  echo base_convert($i, 10, 36), "\n";

Given the last used number, you can convert it back to an integer with intval() increment it and convert the result back to base 36 with base_convert().

<?php

$value = 'bc9z';
$value = intval($value, 36);
++$value;
$value = base_convert($value, 10, 36);
echo $value; // bca0

// or
echo $value = base_convert(intval($value, 36) + 1, 10, 36);
meagar
+1 But beware in systems with 32-bit ints, you will start getting into trouble after 2^31-1=2 147 483 647
Artefacto
A: 

If your string was single case rather than mixed, and didn't contain numerics, then you could literally just increment it:

$testString="AA";
for($x = 0; $x < 65536; $x++) {
    echo $testString++.'<br />';
}

$testString="aa";
for($x = 0; $x < 65536; $x++) {
    echo $testString++.'<br />';
}

But you could possibly make some use of this feature even with a mixed alphanumeric string

Mark Baker
Nit-picky point of annoyance: Don't use string concatenation with `echo`, use commas: `echo $teststring++, '<br />';`
meagar
A: 

To expand on meagar's answer, here is how you can do it with uppercase letters as well and for number arbitrarily big (requires the bcmath extension, but you could as well use gmp or the bigintegers pear package):

function base10ToBase62($number) {
    static $chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
    $result = "";
    $n = $number;
    do {
        $remainder = bcmod($n, 62);
        $n = bcdiv($n, 62);
        $result = $chars[$remainder] . $result;
    } while ($n > 0);

    return $result;
}

for ($i = 10; $i < 99; ++$i) {
    echo base10ToBase62((string) $i), "\n";
}
Artefacto
A: 

Here's an implementation of an incr function which takes a string containing characters [0-9a-zA-Z] and increments it, pushing a 0 onto the front if required using the 'carry-the-one' method.

<?php

function incr($num) {
  $chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
  $parts = str_split((string)$num);

  $carry = 1;
  for ($i = count($parts) - 1; $i >= 0 && $carry; --$i) {
    $value = strpos($chars, $parts[$i]) + 1;
    if ($value >= strlen($chars)) {
      $value = 0;
      $carry = 1;
    } else {
      $carry = 0;
    }
    $parts[$i] = $chars[$value];
  }

  if ($carry)
    array_unshift($parts, $chars[0]);

  return implode($parts);
}

$num = '0';
for ($i = 0; $i < 1000; ++$i) {
  echo $num = incr($num), "\n";
}
meagar
Cheers, this looks perfect! :)
Lee