Generate a 10 digit unique id every time

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • gamernaveen
    New Member
    • Oct 2007
    • 28

    Generate a 10 digit unique id every time

    I am coding a script , where basically the user has to enter his name , choose file , file comments if required and upload.
    The file comments , name , filename will be stored in the database with auto_increment id. The file gets uploaded to the server too. The problem is I want to generate a 10 digit unique code , which makes it simple for the user to download the file , he just has to enter the 10-digit code , and my script will deliver the file to him.

    Everything is fine , but the problem is I am not able to generate the 10 digit unique code. Security is not focused much here , only the id has to be unique everytime WITHOUT FAIL. As the script depends on this unique id for delivering the file (searches the db for this unique id , gets the filename from there and delivers the file).

    I have tried many ways , but cant assure the id will be unique everytime.

    [PHP]<?
    //set the random id length
    $random_id_leng th = 10;
    //generate a random id encrypt it and store it in $rnd_id
    $rnd_id = crypt(uniqid(ra nd(),1));
    //to remove any slashes that might have come
    $rnd_id = strip_tags(stri pslashes($rnd_i d));
    //Removing any . or / and reversing the string
    $rnd_id = str_replace("." ,"",$rnd_id) ;
    $rnd_id = strrev(str_repl ace("/","",$rnd_i d));
    //finally I take the first 10 characters from the $rnd_id
    $rnd_id = substr($rnd_id, 0,$random_id_le ngth);
    echo "Random Id: $rnd_id";
    ?>[/PHP]

    The code above generates an id , but I am not able to assure its unique always.
    What if it returns the same id ?

    Is there a way to do this ? Or any function to convert the auto_increment id from the database to a unique id (encrypted) and result the same auto_increment id when decrypted ?

    Any ways ? Please help me.
    Thanks.
  • Markus
    Recognized Expert Expert
    • Jun 2007
    • 6092

    #2
    Maybe you could pull out, of your db, all the rand IDs assigned and then evaluate them against the rand ID you're going to assign to the newly uploaded file, if the rand ID matches any; create a new one.

    I'm not sure what the coding would be as i have no idea whether you can have a new rand ID generated.

    Not sure..

    Comment

    • gamernaveen
      New Member
      • Oct 2007
      • 28

      #3
      Thats true ,am coding a file uploader-downloader , the user gets the unique id for his file , and whenever he wants , he enters it to download.
      I'll try evaluation from the db , but was looking for a better way. I mean just like credit card numbers , every number is unique with them.

      Comment

      • JeremyMiller
        New Member
        • Sep 2007
        • 69

        #4
        If you don't want the number to be easily guessable, but with moderate security, you have 2 choices as far as I can tell:

        1) Run the database id with a secret seed code through a hash function. Problem here is that hashes are usually more than 10 characters.

        2) Run the database id through a function which is one-to-one. Any ole function will work, but if you make it non-linear, then you'll be doing a bit better. If it's 10 digits that you're talking about though, you only have 10,000,000,000 possible results, so if you can get a function that will return numbers less than 10 billion for all reasonable values of your user id (and pad to the left with zeroes [e.g. 1 would be the code 0000000001]), then you should be good. Oh, and the function would have to return integer results.

        Let's see if I can suggest one and sound less mathematical... I'll come back to this after I do the math (have to create the inverse function too, right?)

        Comment

        • JeremyMiller
          New Member
          • Sep 2007
          • 69

          #5
          hmmm...Messing around with functions for awhile and testing inverses, I'd probably stick with a straight polynomial whose closed-form inverse is easy to find. The big pain here is that they all be integers :) Much easier if that restriction is removed.

          OK. So that's in the dump, what about using letters too? You could then do the username concatenated with the download id with padding as necessary.

          Comment

          • Motoma
            Recognized Expert Specialist
            • Jan 2007
            • 3236

            #6
            Why not just use the primary key (your auto-increment) field padded with zeros?

            Comment

            • ronverdonk
              Recognized Expert Specialist
              • Jul 2006
              • 4259

              #7
              If you have to stick by the 10-char identifier: generate a 9 byte field and add a suffix (range 0-Z), that will make it so that you can have 36 more of the same generated id.
              Code:
              1. generate 9-char unique number $num
              2. check if that number $num is already in database, e.g. 
                  SELECT id FROM table WHERE id LIKE '$num%' ORDER BY id DESC
              3 if any result: get highest id and increment by '1' (you have range '0' to 'Z')
                if no result : store record with id+'0'
              Ronald

              Comment

              • gamernaveen
                New Member
                • Oct 2007
                • 28

                #8
                Originally posted by JeremyMiller
                If you don't want the number to be easily guessable, but with moderate security, you have 2 choices as far as I can tell:

                1) Run the database id with a secret seed code through a hash function. Problem here is that hashes are usually more than 10 characters.

                2) Run the database id through a function which is one-to-one. Any ole function will work, but if you make it non-linear, then you'll be doing a bit better. If it's 10 digits that you're talking about though, you only have 10,000,000,000 possible results, so if you can get a function that will return numbers less than 10 billion for all reasonable values of your user id (and pad to the left with zeroes [e.g. 1 would be the code 0000000001]), then you should be good. Oh, and the function would have to return integer results.

                Let's see if I can suggest one and sound less mathematical... I'll come back to this after I do the math (have to create the inverse function too, right?)
                Wow that sounds great...

                Comment

                • gamernaveen
                  New Member
                  • Oct 2007
                  • 28

                  #9
                  ronverdonk and JeremyMiller , looking forward for your replies.

                  Comment

                  • ronverdonk
                    Recognized Expert Specialist
                    • Jul 2006
                    • 4259

                    #10
                    Before going into all these methods, some simple, some rather complicated, the question is: is there any reason to have this limitation of 10 digits?

                    Using alpha's or extending the number of digits would make all a lot easier and you would extend your range of possible unique's significantly.

                    Ronald

                    Comment

                    • JeremyMiller
                      New Member
                      • Sep 2007
                      • 69

                      #11
                      Originally posted by gamernaveen
                      ronverdonk and JeremyMiller , looking forward for your replies.
                      I did reply -- creating a one-to-one function over the integers whose inverse was also able to be expressed as a function was more work than I wanted to do. Of course, you could do something simple like y=x^2+3, but that's fairly easy to crack (the inverse for the non-mathematical is y=sqrt(x-3) and is valid as the domain is integers greater than 0. You could then pad the number with leading zeroes. I was looking for a function that's a bit more fun, though.

                      Originally posted by ronverdonk
                      Before going into all these methods, some simple, some rather complicated, the question is: is there any reason to have this limitation of 10 digits?

                      Using alpha's or extending the number of digits would make all a lot easier and you would extend your range of possible unique's significantly.

                      Ronald
                      I second that. If you remove the 10 digits limit, you could just return a sha1 hash of the record id joined with a secret seed code and be set to go. That's what I usually do (and sometimes I bind it to the username as well).

                      Comment

                      • Motoma
                        Recognized Expert Specialist
                        • Jan 2007
                        • 3236

                        #12
                        Originally posted by JeremyMiller
                        I second that. If you remove the 10 digits limit, you could just return a sha1 hash of the record id joined with a secret seed code and be set to go. That's what I usually do (and sometimes I bind it to the username as well).
                        Problem with SHA1 is collisions, though with a reduced character set for input, you can all but count that out.

                        Have you thought about using a random number, and keeping the column in your MySQL table UNIQUE? If you follow this route, and the INSERT fails, you can just create another one.

                        Comment

                        • JeremyMiller
                          New Member
                          • Sep 2007
                          • 69

                          #13
                          I never have had any trouble with collisions using sha1 or md5. I've started to use the better hash functions available in PHP 5. Also, binding to the username helps reduce the likelihood of a problem there.

                          I like the idea of a random number, though! For my own code, I'll stick with hashes, though. :)
                          Last edited by JeremyMiller; Oct 20 '07, 01:53 AM. Reason: incorrect word

                          Comment

                          • JeremyMiller
                            New Member
                            • Sep 2007
                            • 69

                            #14
                            Originally posted by gamernaveen
                            The problem is I want to generate a 10 digit unique code , which makes it simple for the user to download the file , he just has to enter the 10-digit code , and my script will deliver the file to him.
                            Just had a thought: Why not provide a login and link(s) to download the file? No funky codes for your end user to remember, just username and password.

                            Comment

                            Working...