Jump to content

Questions about Hashing Photo


doubledee

Recommended Posts

Will people use the same name for a photo?

 

No, but different people could upload the same photo...

 

 

I don't hash my photo names but I use $member_id.time() for file(picture) names.

 

It seems to me I used the hash function for security reasons, but I can't recall?!

 

 

Debbie

 

 

Link to comment
Share on other sites

I'm curious. If two people upload the same photo, but with different names what is the purpose of a hash? Or, what security does hashing the name add to the photo?

 

But back to your original question, no, that will not guarantee a unique name. A hash of the same input will always generate the same output - otherwise the hash would have no purpose. So, if two users upload the same file - if it has the same name or not - it will produce the same hash. But,the content of the file has to be EXACTLY the same. If even one pixel or any header information is different it would produce a different hash. A better approach, IMHO, would be to hash the concatenation of the filename, username and a timestamp. Hashing the actual file contents is too much overhead.

Link to comment
Share on other sites

I'm curious. If two people upload the same photo, but with different names what is the purpose of a hash?

 

I believe the function creates a Hash based on the BITS in the File and not the name, thus my question...

 

 

Or, what security does hashing the name add to the photo?

 

I re-read all of my code in "upload_photo.php" last night and about a 1/3 of it leaves me scratching my head...  (It was definitely a GROUP effort between PHPFreaks, reading online, and da manual!!)

 

It seems someone recommended to use  sha1_file($tempFile); but I don't recall why?

 

One benefit I can see is I *thought* it created a unique File Name everytime you ran it on a photo...

 

But in retrospect, don't Hashes create the same result if you Hash the same thing?  (They must, or you'd never be able to log in?!)

 

All I know, is when someone uploads a Photo, I need a *guaranteed* UNIQUE Filename for that upload so I don't have collisions.

 

 

But back to your original question, no, that will not guarantee a unique name. A hash of the same input will always generate the same output - otherwise the hash would have no purpose. So, if two users upload the same file - if it has the same name or not - it will produce the same hash.

 

Okay, so we agree.

 

Then how can I get a UNIQUE File Name for each upload?

 

 

But,the content of the file has to be EXACTLY the same. If even one pixel or any header information is different it would produce a different hash.

 

Yeah, but that isn't very far-fetched at all...

 

20 geeks could upload the pin-up of some hot chick all from the same source on the Internet...  ;)

 

 

A better approach, IMHO, would be to hash the concatenation of the filename, username and a timestamp. Hashing the actual file contents is too much overhead.

 

Does anyone else out there see a *security* value in using sha1_file($tempFile); ??

 

If not, then Hashing the "username" plus "timestamp" should always be unique, right?

 

 

Debbie

 

Link to comment
Share on other sites

... I use $member_id.time() for file(picture) names.

 

Actually I use member id then an underscore and then time

 

As long as it is UNIQUE and FIXED-WIDTH, I really don't care...

 

Well, and it shouldn't advertise "non-public" info like "member ID", so maybe I disagree some...

 

 

Debbie

 

 

Link to comment
Share on other sites

This is the fun part of scripting.  If what you want is just a unique filename like many sites do when not attached to a specific user, just come up with some fun processes.

 

Here's an idea

[*] explode the name to extract the mime-type

[*] get the member id

[*] get the upload id

[*] multiply the member and upload ids

[*] hash the filename itself

[*] split the filename in half and concatenate half of it back to the end of the initial hash

[*] Merge them together: (result of IDs)-(hash + half-hash).mimetype

 

Completely OTT, but if If that doesn't give you an unique ID, idk what will!

Link to comment
Share on other sites

[*] explode the name to extract the mime-type

 

The mime type is not stored in the filename. *A* file extension is, but not the file's mime type. A file extension does not define the mime type. To properly obtain the mime type you'll want to use either fileinfo or getimagesize.

 

 

[*] multiply the member and upload ids

 

That doesn't necessarily guarantee a unique token because a sum can be reached in multiple ways. For example you can get 40 from both 4*10 and 5*8.

 

 

If all you want is a unique token, most of those suggestions are just...weird. PHP has a function built in to give you unique tokens; uniqid. It is not bullet-proof, but it should be good enough for this task. You can always recursively check to make sure the file name doesn't exist before saving it, just to rule out any 1-in-a-million collisions.

Link to comment
Share on other sites

most of those suggestions are just...weird.

 

Agreed!

 

 

PHP has a function built in to give you unique tokens; uniqid. It is not bullet-proof, but it should be good enough for this task. You can always recursively check to make sure the file name doesn't exist before saving it, just to rule out any 1-in-a-million collisions.

 

What is the risk of flat-out using the Username for the "photo_name"?

 

(At this point I am only allowing ONE Photo per Profile, but that could change...)

 

Is there any reason I want something both UNIQUE and OBSCURE like "847202017743.jpg" for the "photo_name"??  :shrug:

 

Oh, and is it mathematically possible for two different Usernames and Timestamps to resolve to the SAME HASH???

 

If not, then sha1($username . time()) should work, right?

 

 

Debbie

 

Link to comment
Share on other sites

As long as the usernames are unique you should be fine using it as the file name. You wouldn't even have to hash it, just store it as "doubledee.jpg".

 

Oh' date=' and is it mathematically possible for two different Usernames and Timestamps to resolve to the SAME HASH???[/quote']

 

Yes, it is called a collision and it is one of the reasons algorithms like md5 and sha1 are fundamentally broken for password storage. Though I'm sure in a case like this the chances of a collision are probably astronomical, but it's still possible.

Link to comment
Share on other sites

As long as the usernames are unique you should be fine using it as the file name. You wouldn't even have to hash it, just store it as "doubledee.jpg".

 

Except you could argue that is a poor decision as far as Privacy, because now it is recognizable and searchable.

 

You would remember to search for "doubledee.jpg" but not "5491872098301.jpg"...

 

 

Oh' date=' and is it mathematically possible for two different Usernames and Timestamps to resolve to the SAME HASH???[/quote']

 

Yes, it is called a collision and it is one of the reasons algorithms like md5 and sha1 are fundamentally broken for password storage. Though I'm sure in a case like this the chances of a collision are probably astronomical, but it's still possible.

 

So is there a way to Hash (username . time()) so there aren't any collisions??  :confused:

 

 

Debbie

 

Link to comment
Share on other sites

So is there a way to Hash (username . time()) so there aren't any collisions??  :confused:

 

You could use a stronger algorithm (which also adds server overhead) or, like I said, you can recursively check the file name before saving. It's sort of a safety net. Chances are you will never encounter a collision but just in case you do, you can regenerate a new hash and you'll probably be okay.

Link to comment
Share on other sites

(At this point I am only allowing ONE Photo per Profile, but that could change...)

 

For a case where a user only gets to have one file I just name it after their ID since that is always unique per user and makes linking of the file easy.  For a case where a user might be able to have multiple files (say a photo album) I typically just concatenate their ID with the output of uniqid, using something describing the file type as the prefix.  Eg, for a photo album I would do:

$file = $userid.'_'.uniqid('photo');

 

Just to be on the safe side I toss that in a loop that checks if the generated name exists and if so it generates a new one, but such a collision should be very very rare.

 

 

Except you could argue that is a poor decision as far as Privacy, because now it is recognizable and searchable.

 

In the particular case of a profile photo, it is going to be linked to a person's profile by virtue of appearing on their profile or next to any post they make.  Why does it matter if the file name matches their ID/name or not?  It's not like a profile photo is really a private thing anyway.  It is meant to be public as it's basically their "face" on the internet.

 

In the case of other situations, so long as you do something like the above using uniqid or some other form of randomness, nobody will be able to predict users file names.  You could hash the filename to remove the user id if you wanted but I find it to be an unnecessary step.  The most anyone would be able to do by seeing the user id in the name is determine who the file is associated with, but chances are they got to the file in the first place by visiting that user's profile or similar page so they already know that information.

 

 

 

 

 

Link to comment
Share on other sites

For a case where a user only gets to have one file I just name it after their ID since that is always unique per user and makes linking of the file easy.  For a case where a user might be able to have multiple files (say a photo album) I typically just concatenate their ID with the output of uniqid, using something describing the file type as the prefix.  Eg, for a photo album I would do:

$file = $userid.'_'.uniqid('photo');

 

Just to be on the safe side I toss that in a loop that checks if the generated name exists and if so it generates a new one, but such a collision should be very very rare.

 

Except you should never expose the "Member ID" publicly.

 

 

I am leaning towards something like this...

$photoName = sha1($memberID . uniqid(mt_rand(), true));

 

And then also check to make sure it is unique in the database, before doing an INSERT.

 

 

---------

If I wanted to be really neurotic, I could use my Password code like this...

 

// ********************
// Generate New Salt.	*
// ********************
$newSalt = substr(sha1(uniqid(mt_rand(), true)), 0, 10);


// ********************
// Generate New Hash.	*
// ********************
$newHash = hash_hmac('sha512', $newPass . $newSalt, VINEGAR);

 

8)

 

 

Debbie

 

Link to comment
Share on other sites

Except you should never expose the "Member ID" publicly.

 

Why?  There's no problem with exposing ID's.

 

I don't have a solid response, other than that sure doesn't feel right... 

 

It's not really a big deal. This very site exposes user ID's in their profile link. Your ID is 113246.

Link to comment
Share on other sites

... I use $member_id.time() for file(picture) names.

 

Actually I use member id then an underscore and then time

 

As long as it is UNIQUE and FIXED-WIDTH, I really don't care...

 

Well, and it shouldn't advertise "non-public" info like "member ID", so maybe I disagree some...

 

 

Debbie

 

Okay #113246

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.