简体   繁体   中英

Globally unique random name for Images

I am trying to write code for generating globally unique name for images that are to be uploaded by users from iOS app to server. The names should be randomly generated and should be unique so that the images are not overwritten/replaced.

Here's my code for generating random and unique strings:

+ (NSString *)generateRandNameWithLength:(int)len
{

    NSString *letters = [NSString stringWithFormat:@"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ%@0123456789", [HJUtilities generateUniqueApId]];
    NSMutableString *randomString = [NSMutableString stringWithCapacity: len];

    for (int i=0; i<len; i++) {
        [randomString appendFormat: @"%C", [letters characterAtIndex: arc4random() % [letters length]]];
    }

    return randomString;
}

Where:

+ (NSString *)generateUniqueApId
{
    NSString *appId = (__bridge NSString *) CFUUIDCreateString (NULL, CFUUIDCreate(NULL));

    return appId;
}

returns a UUID.

Now I'm not sure whether this is the correct code for generating globally unique strings. I don't know how to verify this to be certain that no user will overwrite another user's image.

Note: I'm using Amazon Web services for storage. And one common bucket will be used for all the images of all users. So, its required that images names should be unique.

There is no need for the code you have. All you need is the CFUUIDCreateString function. This will be unique across all users on all devices.

From the docs for CFUUID :

UUIDs (Universally Unique Identifiers), also known as GUIDs (Globally Unique Identifiers) or IIDs (Interface Identifiers), are 128-bit values guaranteed to be unique. A UUID is made unique over both space and time by combining a value unique to the computer on which it was generated—usually the Ethernet hardware address—and a value representing the number of 100-nanosecond intervals since October 15, 1582 at 00:00:00.

The code you have now is definitely not guaranteed to be unique.

You're overcomplicating it. Just get a UUID using CFUUIDCreateString and use that string. Adding extra layers of randomness isn't going to help. In fact, it's probably going to make things worse by increasing the chance of a name collision.

The only argument against using a UUID directly is that it may be possible to identify the source of the upload, since the UUID is (or can be) generated using device's MAC address, which is specific to the hardware. You won't be able to identify a user with nothing but a UUID, but you would be able to say "this collection of UUIDs came from the same device" or "this UUID came from this device". (See RFC 4122 for the various UUID formats and a discussion of this issue in section 4.5.)

If anonymity is a concern, running the UUID through a hash function, like SHA1 or MD5, would be good enough to make it unidentifiable.

Using a loop where you "add randomness" by mixing in random numbers is like shaking a dice for a few seconds versus an hour: the only difference is that you're rubbing sweat onto the dice.

There is a new class added in iOS 6.0

@interface NSUUID : NSObject <NSCopying, NSSecureCoding>

To simplify the memory management you for sure can use it

至于本地唯一的字符串(您可以将其用作文件名的一部分),这很方便:

[[NSProcessInfo processInfo] globallyUniqueString]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM