I'm trying to covert this bit of C code to Cocoa and I'm struggling to figure out how.
char *deskey = "123 456 789 101 112 131 415 161";
unsigned char key[16];
memset(key, 0, sizeof(key));
sscanf(deskey, "%o %o %o %o %o %o %o %o",
(int*)&key[0], (int*)&key[1], (int*)&key[2],
(int*)&key[3], (int*)&key[4], (int*)&key[5],
(int*)&key[6], (int*)&key[7]);
I've tried using NSMutableArray and NSData but having no luck. I was able to scan the string and pull out the numbers, but I'm not sure how to store into NSData after that.
NSMutableArray *enckey = [[[NSMutableArray alloc] init] autorelease];
NSScanner *scanner = [NSScanner scannerWithString:self.deskey];
int pos = 0;
while ([scanner isAtEnd] == NO) {
if ([scanner scanInt:&pos]) {
[enckey addObject:[NSString stringWithFormat:@"%o", pos]];
}
else {
NSLog(@"Your DES key appears to be invalid.");
return;
}
}
Basically trying to convert ascii DES key to string to use for Triple DES encryption. Any help is greatly appreciated, thank you!
@Keenan "I was hoping to avoid using sscanf and char* in place of the Cocoa classes". Well you can do that, but what are you hoping to produce? If you want a byte array as the result then you need to stick to unsigned char[]
, and that begs the question why you'd do the parsing on NSString
in the first place.
Here is an Objective-C translation of your C code. Note that octal is seen as ancient history by Cocoa so its parsing classes only deal with decimal and hexadecimal, so you need to write your own or use a standard C function (strtol
below).
This example produces both a unsigned char[]
and an NSMutableArray
- pick one.
// There are no checks in the code, like in the original...
// BTW 789 is not an octal number...
NSString *descKey = @"123 456 789 101 112 131 415 161"; // char *deskey = "123 456 789 101 112 131 415 161";
// pick one...
NSMutableArray *keyObjC = [NSMutableArray new]; // unsigned char key[16];
unsigned char keyC[16];
// memset(key, 0, sizeof(key));
// As @JeremyP has pointed out the sscanf is wrong as %o produces a 4-byte value and you only want a 1-byte one.
// In C you would therefore need key to be an array of ints and then assign each element to a byte (unsigned char),
// or parse a different way.
unsigned ix = 0; // for keyC choice only
NSArray *numbers = [descKey componentsSeparatedByString:@" "]; // sscanf(deskey, "%o %o %o %o %o %o %o %o",
for (NSString *aNumber in numbers) // (int*)&key[0], (int*)&key[1], (int*)&key[2],
{ // (int*)&key[3], (int*)&key[4], (int*)&key[5],
// (int*)&key[6], (int*)&key[7]);
unsigned char next = (unsigned char)strtol([aNumber UTF8String], NULL, 8);
keyC[ix++] = next; // for keyC choice
[keyObjC addObject:[NSNumber numberWithUnsignedChar:next]]; // keyObjC choice
}
If you want to approach the one line of your Python just compress the iteration to:
for (NSString *aNumber in [descKey componentsSeparatedByString:@" "]) { [keyObjC addObject:[NSNumber numberWithUnsignedChar:(unsigned char)strtol([aNumber UTF8String], NULL, 8)]]; }
but it is still longer of course!