-
-
Save datalogics-robl/6215182 to your computer and use it in GitHub Desktop.
#import "NSUUID+DLExtensions.h" | |
#import <CommonCrypto/CommonDigest.h> | |
@implementation NSUUID (DLExtensions) | |
+ (NSUUID*)withNamespaceUUID:(NSUUID*)namespace name:(NSString*)name | |
{ | |
NSString *concatenatedName = [[namespace UUIDString] stringByAppendingString:name]; | |
NSData *data = [concatenatedName dataUsingEncoding:NSUTF8StringEncoding]; | |
uint8_t digest[CC_SHA1_DIGEST_LENGTH]; | |
uuid_t bytes; | |
CC_SHA1(data.bytes, data.length, digest); | |
// TEMPORARY--Just log the new UUID | |
NSMutableString *dontUse = [NSMutableString stringWithCapacity:CC_SHA1_DIGEST_LENGTH]; | |
for (int i = 0; i < CC_SHA1_DIGEST_LENGTH; i++) { | |
[dontUse appendFormat:@"%02x", digest[i]]; | |
} | |
NSLog(@"CRYPTO'D STRING = %@", dontUse); | |
// END TEMPORARY | |
// Fill in the UUID bytes, masking in the version and reserved bits | |
bytes[0] = digest[0]; // time_low | |
bytes[1] = digest[1]; | |
bytes[2] = digest[2]; | |
bytes[3] = digest[3]; | |
bytes[4] = digest[4]; // time_mid | |
bytes[5] = digest[5]; | |
bytes[6] = ((digest[6] & 0x0F) | 0x50); // time_hi_and_version | |
bytes[7] = digest[7]; | |
bytes[8] = ((digest[8] & 0x3F) | 0xB0); // clock_seq_hi_and_reserved | |
bytes[9] = digest[9]; // clock_seq_low | |
bytes[10] = digest[10]; // node | |
bytes[11] = digest[11]; | |
bytes[12] = digest[12]; | |
bytes[13] = digest[13]; | |
bytes[14] = digest[14]; | |
bytes[15] = digest[15]; | |
// TEMPORARY | |
NSLog(@"Computed UUID: %@", [[[[NSUUID alloc] initWithUUIDBytes:bytes] autorelease] UUIDString]); | |
// END TEMPORARY | |
return [[[NSUUID alloc] initWithUUIDBytes:bytes] autorelease]; | |
} | |
@end |
Is it possible to change this one?
Say guys, did you ever figure out a workable objective C implementation of UUID5 (or UUID3)? I see this was attempted some time ago (not sure if it was intended to be public from the comments there). Just curious before I attempt implementing RFC 4122 if you guys found a way beyond this.
Never mind, implementation wasn't hard, got it working.
Just in case anyone needs uuid5 calculation in url namespace https://gist.github.com/superduper/177aab4b9700e41103e3
I had problems with both Rob and Victor's implementations because I needed to interoperate with (and match) uuid5 strings generated by a python backend. Using their code as a starting point I've created a drop-in NSUUID category that works correctly. It's MIT licensed so you are free to do with it as you like.
https://gist.github.com/eliburke/1a55ed616bb15a7f908b
If you prefer to fix Rob's code, you need to use the raw bytes from the namespace UUID and change his clock_seq_hi_and_reserved line to use 0x80 instead of 0xB0.
If you prefer to fix Victor's code, change his calculation of bytes[8] from
bytes[8] = ((bytes[8] | 0x40) & 0x7F); // bad code, sets bits to 0100 xxxx
bytes[8] = ((bytes[8] & 0x3F) | 0x80); // good code, sets bits to 10xx xxxx
BTW, you can, and I recommend it, make these private. Anybody with the link can still read them.