Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6624171
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 25, 20262026-05-25T21:37:13+00:00 2026-05-25T21:37:13+00:00

This is for a file sharing website. In order to make sure a passcode,

  • 0

This is for a file sharing website. In order to make sure a “passcode”, which is unique to each file, is truely unique, I’m trying this:

$genpasscode = mysql_real_escape_string(sha1($row['name'].time())); //Make passcode out of time + filename.
    $i = 0;
    while ($i < 1) //Create new passcode in loop until $i = 1;
    {
        $query = "SELECT * FROM files WHERE passcode='".$genpasscode."'";
        $res = mysql_query($query);
        if (mysql_num_rows($res) == 0) // Passcode doesn't exist yet? Stop making a new one!
        {
            $i = 1;
        }
        else // Passcode exists? Make a new one!
        {
            $genpasscode = mysql_real_escape_string(sha1($row['name'].time()));
        }
    }

This really only prevents a double passcode if two users upload a file with the same name at the exact same time, but hey better safe than sorry right? My question is; does this work the way I intend it to? I have no way to reliably (read: easily) test it because even one second off would generate a unique passcode anyway.

UPDATE:
Lee suggest I do it like this:

do {
    $query = "INSERT IGNORE INTO files 
       (filename, passcode) values ('whatever', SHA1(NOW()))";
    $res = mysql_query($query);
} while( $res && (0 == mysql_affected_rows()) )

[Edit: I updated above example to include two crucial fixes. See my answer below for details. -@Lee]

But I’m afraid it will update someone else’s row. Which wouldn’t be a problem if filename and passcode were the only fields in the database. But in addition to that there’s also checks for mime type etc. so I was thinking of this:

//Add file
        $sql = "INSERT INTO files (name) VALUES ('".$str."')";
        mysql_query($sql) or die(mysql_error());

        //Add passcode to last inserted file
        $lastid = mysql_insert_id();
        $genpasscode = mysql_real_escape_string(sha1($str.$lastid.time())); //Make passcode out of time + id + filename.
        $sql = "UPDATE files SET passcode='".$genpasscode."' WHERE id=$lastid";
        mysql_query($sql) or die(mysql_error());

Would that be the best solution? The last-inserted-id field is always unique so the passcode should be too. Any thoughts?

UPDATE2: Apperenatly IGNORE does not replace a row if it already exists. This was a misunderstanding on my part, so that’s probably the best way to go!

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-25T21:37:13+00:00Added an answer on May 25, 2026 at 9:37 pm

    Strictly speaking, your test for uniqueness won’t guarantee uniqueness under a concurrent load. The problem is that you check for uniqueness prior to (and separately from) the place where you insert a row to “claim” your newly generated passcode. Another process could be doing the same thing, at the same time. Here’s how that goes…

    Two processes generate the exact same passcode. They each begin by checking for uniqueness. Since neither process has (yet) inserted a row to the table, both processes will find no matching passcode in database, and so both processes will assume that the code is unique. Now as the processes each continue their work, eventually they will both insert a row to the files table using the generated code — and thus you get a duplicate.

    To get around this, you must perform the check, and do the insert in a single “atomic” operation. Following is an explanation of this approach:


    If you want passcode to be unique, you should define the column in your database as UNIQUE. This will ensure uniqueness (even if your php code does not) by refusing to insert a row that would cause a duplicate passcode.

    CREATE TABLE files (
      id int(10) unsigned NOT NULL auto_increment PRIMARY KEY,
      filename varchar(255) NOT NULL,
      passcode varchar(64) NOT NULL UNIQUE,
    )
    

    Now, use mysql’s SHA1() and NOW() to generate your passcode as part of the insert statement. Combine this with INSERT IGNORE ... (docs), and loop until a row is successfully inserted:

    do {
        $query = "INSERT IGNORE INTO files 
           (filename, passcode) values ('whatever', SHA1(NOW()))";
        $res = mysql_query($query);
    } while( $res && (0 == mysql_affected_rows()) )
    
    if( !$res ) {
       // an error occurred (eg. lost connection, insufficient permissions on table, etc)
       // no passcode was generated.  handle the error, and either abort or retry.
    } else {
       // success, unique code was generated and inserted into db.
       // you can now do a select to retrieve the generated code (described below)
       // or you can proceed with the rest of your program logic.
    }
    

    Note: The above example was edited to account for the excellent observations posted by @martinstoeckli in the comments section. The following changes were made:

    • changed mysql_num_rows() (docs) to mysql_affected_rows() (docs) — num_rows doesn’t apply to inserts. Also removed the argument to mysql_affected_rows(), as this function operates on the connection level, not the result level (and in any case, the result of an insert is boolean, not a resource number).
    • added error checking in the loop condition, and added a test for error/success after loop exits. The error handling is important, as without it, database errors (like lost connections, or permissions problems), will cause the loop to spin forever. The approach shown above (using IGNORE, and mysql_affected_rows(), and testing $res separately for errors) allows us to distinguish these “real database errors” from the unique constraint violation (which is a completely valid non-error condition in this section of logic).

    If you need to get the passcode after it has been generated, just select the record again:

    $res = mysql_query("SELECT * FROM files WHERE id=LAST_INSERT_ID()");
    $row = mysql_fetch_assoc($res);
    $passcode = $row['passcode'];
    

    Edit: changed above example to use the mysql function LAST_INSERT_ID(), rather than PHP’s function. This is a more efficient way to accomplish the same thing, and the resulting code is cleaner, clearer, and less cluttered.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I built a website and I have this png file which is a bordered
I have this file file.txt which I want to split into many smaller ones.
In this MSDN article on file sharing mode with std::ofstream , Microsoft writes: To
My app is using iTunes file sharing which exposes everything in the Documents directory
I have a simple file sharing application. Users are sending data among each other
I am trying to run a file sharing software behind NAT. As I am
Okay, so i am trying to start hosting my own file sharing site, i
OK: I'm implementing File Sharing in an iPhone OS app, and of course this
I'm constructing a file sharing system which needs to transmit a single file to
Using this file as source, I have a situation where I need to retrieve

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.