Question

I am attempting to create a fingerprint for an object in coreData, and want to set it as attribute to an object. I figured CFBitArray is the way to go.

I am trying to figure out how to save this per object:

Here is an example

Object

attributes: Name: Fingerprint ("01010101010101010101010110") etc...

This is used to try to match with a master print

Any suggestions?

Was it helpful?

Solution

You'd have to convert that to/from something Core Data understands, and save the converted value. There are a couple of possibilities, both of which involve getting the actual bits via CFBitVectorGetBits. Once you have that, you can

  • Save them in an NSData using something like +dataWithBytes:length:, and put that in a binary-type attribute on a managed object. Or...
  • Depending on the number of bytes you're using, save them in an NSNumber using something like +numberWithLong: (or whatever is long enough for the number of bits). Then put that in one of Core Data's integer types-- again, choosing whatever size fits your bits.

You can make the conversion either by using custom accessor methods on your NSManagedObject subclass, or by using the transformable Core Data attribute type and a value transformer class. For the latter you'd subclass NSValueTransformer and implement your conversions there (Apple provides a couple of examples of this).

Depending on what you're actually doing, you might want to consider using NSIndexSet instead of CFBitVectorRef. If nothing else, it conforms to NSCoding-- which means you can use a transformable attribute but rely on Core Data's default value transformer instead of writing your own.

You might also find it a lot simpler to just use one of the integer types and rely on bitwise operators to determine if a bit is set. Then you don't need to do anything special with Core Data, you just choose the appropriately-sized integer type.

OTHER TIPS

Why are you not just storing NSData? It is way, way easier to store binary data inside NSData than inside CFBitvectorRef.

If you're trying to store a hash / fingerprint of something, I assume you're creating a SHA-256 hash with CC_SHA256_Init, _Update and _Final. Those will give you a so-called digest which is a fingerprint of the data you pass into the CC_SHA256_Update.

// Create the context:
CC_SHA256_CTX shaContext;
CC_SHA256_Init(&shaContext);
// For each value:
CC_SHA256_Update(&shaContext, &v, sizeof(v));
// Get the fingerprint / digest:
unsigned char digest[CC_SHA256_DIGEST_LENGTH];
CC_SHA256_Final(digest, &shaContext);
NSData *fingerprint = [NSData dataWithBytes:digest length:sizeof(digest)];

Then you can store that fingerprint into a Core Data attribute that's Binary Data.

Depending on the type of v, you might have to change the call to CC_SHA256_Update(). If you do this on an NSObject, you need to call it for each instance variable that you're interested in (that should be part of the fingerprint), e.g. if you have

@property (nonatomic) int32_t count;
@property (nonatomic, copy) NSString *name;

you'd do

int32_t v = self.count
CC_SHA256_Update(&shaContext, &v, sizeof(v));

NSData *d = [self.name dataUsingEncoding:NSUTF8Stringencoding];
CC_SHA256_Update(&shaContext, [data bytes], [data length]);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top