Welcome Guest, Not a member yet? Register   Sign In
How to generate a random serial number
#1

[eluser]Unknown[/eluser]
Hi,

This is what I want:

I'm generating a serial number and I need to make sure it doesn't exist already. So I generate the string, query the result in the table, if it doesn't exist I will record it, if it does I need to run the function again without having to refresh the page.

This is my code so far:
Code:
function generate_serial($length){
    
        $len=$length;
        $base='JKLMNOPQRS123456789';
        $max=strlen($base)-1;
        $rand_num='';
        mt_srand((double)microtime()*1000000);
        while (strlen($rand_num)<$len+1)
        $rand_num.=$base{mt_rand(0,$max)};
        
        $this->db->select("user");
        $this->db->from('serial');
        $this->db->where("user = '$rand_num'");
        $query = $this->db->get();
        
        if($query->num_rows() > 0)
        {
            // This is where I want to run again this same function to generate a new serial
            // $this->generate_serial($lenght); (I tried it but it doesn't seem to work this way!)
        }
        else
        {
            return $rand_num;
        }
    
    }

I have another function to insert the data into the table that is called from the controller.Thanks for your help,
#2

[eluser]jedd[/eluser]
Hi cleos and welcome to the CI forums.

You've got a pattern problem there - you need to have the function that generates the actual serial number as a separate function - perhaps a private function (start with an underscore). That way you can call it, then consult the database, ideally via a call to one of the methods in your new Model! - and repeat as necessary.

Can I ask though - what's the actual problem you're trying to solve? You've described how the solution you've come up with doesn't work .. and this is a common problem when trying to think about solutions - you start to lose sight of the original, base, fundamental (etc) problem.

For instance, I'd suggest that the table you're generating a new row for here should use an id field that's an autoincrement unsigned integer. Randomly generated anythings are expensive, and even more so if you can't guarantee uniqueness. So if you're perversely opposed to a guaranteed unique integer primary key here, and want something less integery for some other purpose - then I'd suggest either - use md5 (cheap) to generate a reasonably-likely-to-be-unique string based on the integer (and any other data you've got for that row). You may have luck with utilising some substr() of such an md5 output. It's probably cheaper to use the md5 function and repeat on duplicates than your own random number based function.

Second alternative - use UUID's - either dr uuid(?) - or one of the other php libraries for generating UUIDs - or if you're using MySQL, what I've done in the past is have a MY_Model call that asks MySQL for a UUID using its built-in. From memory, MySQL provides v5 UUIDs, so while safety can't be guaranteed, it should be reasonably unlikely you'll hit any duplicates in the next few lifetimes.
#3

[eluser]skunkbad[/eluser]
I use function to apply a unique user id, and it checks the db to make sure it is truly unique. You may be able to adapt this to your needs:

Code:
public function get_unused_id()
{
    // Create a random user id
    $random_unique_int = mt_rand(1200,999999999);

    // Make sure the random user_id isn't already in use
    $this->CI = get_instance();
    $this->CI->db->where('user_id', $random_unique_int);
    $query = $this->CI->db->get_where($this->CI->config->item('user_table'));
    if ($query->num_rows() > 0)
    {
        $query->free_result();

        // If the random user_id is already in use, get a new number
        $this->get_unused_id();
    }

    return $random_unique_int;
}
#4

[eluser]theshiftexchange[/eluser]
if you really want to - you could do this (in pseudocode)

Code:
function main()
{
    $continue = false;
    while $continue === false
    {
        $rand = $this->_create_random_number();
        if ($this->db->check_if_unique($rand) === true)
             $continue = true;
    }

}

function _create_random_number()
{
    $rand_x = rand();
    return $rand_x;
}
#5

[eluser]n0xie[/eluser]
Why not use uniqid?

http://php.net/manual/en/function.uniqid.php
#6

[eluser]Federico BaƱa[/eluser]
if you use uniqid you can save the call to the database...

another solution could be, assuming you generate one serial key per user:
Code:
$username = $this->session->userdata('username');
$salt = 'whatever_you_want';
$serial = md5($salt . $username); // your unique serial key (and the only serial key this user will ever have)

or yet another:
Code:
$unique = uniqid() . uniqid();
$and32chars = md5($unique);

hope this is useful
#7

[eluser]Vheissu[/eluser]
This is seriously the best thing I have ever purchased online and only $5: http://codecanyon.net/item/php-key-gener...ass/108433 - it lets you generate serials and authenticate them. Also lets you create serials that have common digits and whatnot in them similar to Windows product keys. Saved me the hassle of writing my own code.
#8

[eluser]skunkbad[/eluser]
I wish uniqid() had a parameter that would make it only create numeric IDs.
#9

[eluser]Unknown[/eluser]
[quote author="jedd" date="1293352821"]Hi cleos and welcome to the CI forums.

You've got a pattern problem there ... [/quote]

Would you please explain to me the concept of cheap vs expensive when it comes to code and why md5 is cheaper than mt_srand. I might be wrong but I thought that I first would need an integer and then encode it with md5 which take us to square one. Also, about the pattern, why do you think it is a problem to contrast $rand_num with the db in the same function.

Thanks a lot for your help, thanks to this forum, I have learn so much about CI and I have still a lot to cover.
#10

[eluser]jedd[/eluser]
There are two things generally troublesome with rand style functions - they are computationally expensive, and they are seldom random. Wink

The pattern problem I refer to was generating a number in the same fumction that you want to test uniqueness in - it's doable, but not very elegant. My first paragraph, and the subsequent two posts from other people, explained the benefit of having the generate function external. That you asked, indicates you also worked out that it's a problem to do both things in one function.

As to expense - I am a week away from access to a computer (on my phone at the moment) so I can't test performance, but my gut feel is that a php function you write that relies upon rand() will not beat a C library deterministic function. I may, of course, be wrong. It's easy enough to test if you're curious, but be sure to use a big sample set.

And, as I say, integers are preferable for a couple of reasons, if you can use them instead.




Theme © iAndrew 2016 - Forum software by © MyBB