Short unique id in php

前端 未结 16 866
没有蜡笔的小新
没有蜡笔的小新 2020-11-29 17:34

I want to create a unique id but uniqid() is giving something like \'492607b0ee414\'. What i would like is something similar to what tinyurl gives:

相关标签:
16条回答
  • 2020-11-29 18:10

    Letters are pretty, digits are ugly. You want random strings, but don't want "ugly" random strings?

    Create a random number and print it in alpha-style (base-26), like the reservation "numbers" that airlines give.

    There's no general-purpose base conversion functions built into PHP, as far as I know, so you'd need to code that bit yourself.

    Another alternative: use uniqid() and get rid of the digits.

    function strip_digits_from_string($string) {
        return preg_replace('/[0-9]/', '', $string);
    }
    

    Or replace them with letters:

    function replace_digits_with_letters($string) {
        return strtr($string, '0123456789', 'abcdefghij');
    }
    
    0 讨论(0)
  • 2020-11-29 18:11

    Make a small function that returns random letters for a given length:

    <?php
    function generate_random_letters($length) {
        $random = '';
        for ($i = 0; $i < $length; $i++) {
            $random .= chr(rand(ord('a'), ord('z')));
        }
        return $random;
    }
    

    Then you'll want to call that until it's unique, in pseudo-code depending on where you'd store that information:

    do {
        $unique = generate_random_letters(6);
    } while (is_in_table($unique));
    add_to_table($unique);
    

    You might also want to make sure the letters do not form a word in a dictionnary. May it be the whole english dictionnary or just a bad-word dictionnary to avoid things a customer would find of bad-taste.

    EDIT: I would also add this only make sense if, as you intend to use it, it's not for a big amount of items because this could get pretty slow the more collisions you get (getting an ID already in the table). Of course, you'll want an indexed table and you'll want to tweak the number of letters in the ID to avoid collision. In this case, with 6 letters, you'd have 26^6 = 308915776 possible unique IDs (minus bad words) which should be enough for your need of 10000.

    EDIT: If you want a combinations of letters and numbers you can use the following code:

    $random .= rand(0, 1) ? rand(0, 9) : chr(rand(ord('a'), ord('z')));
    
    0 讨论(0)
  • 2020-11-29 18:12

    Really simple solution:

    Make the unique ID with:

    $id = 100;
    base_convert($id, 10, 36);
    

    Get the original value again:

    intval($str,36);
    

    Can't take credit for this as it's from another stack overflow page, but I thought the solution was so elegant and awesome that it was worth copying over to this thread for people referencing this.

    0 讨论(0)
  • 2020-11-29 18:14

    If you do like a longer version of unique Id use this:
    $uniqueid = sha1(md5(time()));

    0 讨论(0)
  • 2020-11-29 18:15

    You can also do it like tihs:

    public static function generateCode($length = 6)
        {
            $az = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
            $azr = rand(0, 51);
            $azs = substr($az, $azr, 10);
            $stamp = hash('sha256', time());
            $mt = hash('sha256', mt_rand(5, 20));
            $alpha = hash('sha256', $azs);
            $hash = str_shuffle($stamp . $mt . $alpha);
            $code = ucfirst(substr($hash, $azr, $length));
            return $code;
        }
    
    0 讨论(0)
  • 2020-11-29 18:15

    Best Answer Yet: Smallest Unique "Hash Like" String Given Unique Database ID - PHP Solution, No Third Party Libraries Required.

    Here's the code:

    <?php
    /*
    THE FOLLOWING CODE WILL PRINT:
    A database_id value of 200 maps to 5K
    A database_id value of 1 maps to 1
    A database_id value of 1987645 maps to 16LOD
    */
    $database_id = 200;
    $base36value = dec2string($database_id, 36);
    echo "A database_id value of 200 maps to $base36value\n";
    $database_id = 1;
    $base36value = dec2string($database_id, 36);
    echo "A database_id value of 1 maps to $base36value\n";
    $database_id = 1987645;
    $base36value = dec2string($database_id, 36);
    echo "A database_id value of 1987645 maps to $base36value\n";
    
    // HERE'S THE FUNCTION THAT DOES THE HEAVY LIFTING...
    function dec2string ($decimal, $base)
    // convert a decimal number into a string using $base
    {
        //DebugBreak();
       global $error;
       $string = null;
    
       $base = (int)$base;
       if ($base < 2 | $base > 36 | $base == 10) {
          echo 'BASE must be in the range 2-9 or 11-36';
          exit;
       } // if
    
       // maximum character string is 36 characters
       $charset = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
    
       // strip off excess characters (anything beyond $base)
       $charset = substr($charset, 0, $base);
    
       if (!ereg('(^[0-9]{1,50}$)', trim($decimal))) {
          $error['dec_input'] = 'Value must be a positive integer with < 50 digits';
          return false;
       } // if
    
       do {
          // get remainder after dividing by BASE
          $remainder = bcmod($decimal, $base);
    
          $char      = substr($charset, $remainder, 1);   // get CHAR from array
          $string    = "$char$string";                    // prepend to output
    
          //$decimal   = ($decimal - $remainder) / $base;
          $decimal   = bcdiv(bcsub($decimal, $remainder), $base);
    
       } while ($decimal > 0);
    
       return $string;
    
    }
    
    ?>
    
    0 讨论(0)
提交回复
热议问题