title: How to generate a unique non-guessable activation link in PHP
body: <p>I've been reading articles all day on the subject but am not sure how to proceed.</p>
  
  <p>I have a MySQL table of users with a primary key of UUID_SHORT() values and an email field, which is also unique. I need to be able to generate an always unique, non-guessable ID to use in an activation URL. Something like this:</p>
  
  <pre><code>http://example.com/activate.php?id=tKd32f
  </code></pre>
  
  <p>After reading this question: <a href="https://stackoverflow.com/questions/742013/how-to-code-a-url-shortener">How to code a URL shortener?</a></p>
  
  <p>I've implemented a base58 encoding method that I'm trying to use with the UUID_SHORT() value representing the user, as generated by the MySQL server.</p>
  
  <pre><code>&lt;?php
  function base58_encode($num, $alphabet) 
  {                           
      $base_count = strlen($alphabet);
      $alphabet =  str_split($alphabet);
      echo "base_count: " . $base_count . "&lt;br&gt;";
      $encoded = '';
      while ($num &gt;= $base_count) 
      {
          $div = $num/$base_count;
          echo "div: " . $div . "&lt;br&gt;";
          $mod = ($num-($base_count*intval($div)));
          echo "mod: " . $mod . "&lt;br&gt;";
          echo "alphabet[$mod]: " . $alphabet[$mod] . "&lt;br&gt;";                             
          $encoded = $alphabet[$mod] . $encoded;
          echo "encoded: " . $encoded . "&lt;br&gt;";
          $num = intval($div);
          echo "num: " . $num . "&lt;br&gt;";
          echo "------------------------------&lt;br&gt;";
      }
  
      if ($num) $encoded = $alphabet[$num] . $encoded;
  
      return $encoded;
  }
  
  $alphabet = "123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ";
  echo "WORKS =&gt; " . base58_encode(3707787591, $alphabet) . "&lt;br&gt;&lt;br&gt;"; // some random number
  echo "DOES NOT WORK =&gt; " . base58_encode(23298059492392988, $alphabet); // one of the unique IDs in my database
  ?&gt;
  </code></pre>
  
  <p>If I use a 10 digit number, it works. But if I use the longer UUID_SHORT value, I get an undefined offset error because $num = intval($div) returns a negative number when its param is too large. I can't seem to figure out why, but it seems to be related to: <a href="http://ca1.php.net/intval" rel="nofollow noreferrer">http://ca1.php.net/intval</a></p>
  
  <p>My questions:</p>
  
  <ol>
  <li><p>Is this even the correct approach? Should I be using the UUID_SHORT value to generate the activation code or is that too guessable? If I do a SELECT UUID_SHORT() multiple times on the MySQL server, you can see this value increment by 1 (which worries me).</p></li>
  <li><p>If this base58_encode is the correct approach, how would I resolve this error? How can I get a shorter activation code, not unlike goo.gl's url shortener service. How do they do it? I couldn't find a clear answer on this.</p></li>
  <li><p>Should I be using something more along the lines of this? <a href="https://stackoverflow.com/questions/876139/how-to-generate-a-secure-activation-string-in-php">How to generate a secure activation string in php?</a>
  However, this generates a really long ID. Not really necessary in my case and it makes for uglier activation URLs.</p></li>
  </ol>
  
  <p>I plan on expiring my URLs after a certain period of time, but the IDs need to always be unique (and ideally, short enough). I also don't need to later decode the value because I will map the uniquely generated ID to the user ID in the database. What is the best approach here?</p>
  
  <p>Thank you for your time.</p>