我正试图将这段C代码转换为Cocoa,我正在努力弄清楚如何。
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]);
我尝试过使用NSMutableArray和NSData,但没有运气。我能够扫描字符串并提取数字,但我不确定如何在此之后存储到NSData。
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;
}
}
基本上尝试将ascii DES密钥转换为字符串以用于Triple DES加密。非常感谢任何帮助,谢谢!
答案 0 :(得分:1)
@Keenan“我希望避免使用sscanf和char *代替Cocoa类”。那么你可以做到,但是你希望生产什么?如果你想要一个字节数组那么你需要坚持unsigned char[]
,这就引出了为什么你首先要在NSString
上进行解析的问题。
以下是C代码的Objective-C转换。请注意,八进制被Cocoa视为古代历史,因此它的解析类只处理十进制和十六进制,因此您需要编写自己的或使用标准C函数(下面strtol
)。
此示例同时生成unsigned char[]
和NSMutableArray
- 选择一个。
// 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
}
如果你想接近Python的一行,只需将迭代压缩为:
for (NSString *aNumber in [descKey componentsSeparatedByString:@" "]) { [keyObjC addObject:[NSNumber numberWithUnsignedChar:(unsigned char)strtol([aNumber UTF8String], NULL, 8)]]; }
但它当然更长了!
答案 1 :(得分:0)
快速而肮脏的方法是采用原始代码
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]);
并添加以下行:
NSData* keyData = [NSData dataWithBytes: key length: sizeof key];
除了你的sscanf看起来非常错误。密钥的元素是字符,而不是整数。
答案 2 :(得分:0)
由于CRD已经很好地向您展示了正确的解决方案,我将使用我的答案来解释您的解决方案无法解决的原因。
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]);
说谎编译器永远不会解决问题。
key
是一个unsigned char
的数组。告诉编译器,在对sscanf
的函数调用中,指向数组的指针是指向int
的指针并不能使它们如此;每个人指向的存储仍然是unsigned char
的存储空间,而不再存储。
这样做的结果是,每次尝试在您提供的地址中存储一个int
会覆盖前一个int
的四分之三。 的结果是sscanf
仅仅是与memset
做同样事情的一种更难的方式。
我说“多一点”而不是“不再”是有原因的:sscanf
调用还会在数组末尾写入sizeof(int) - sizeof(unsigned char)
个字节,因此您还会粉碎堆栈并进行设置发生潜在的崩溃。
if ([scanner scanInt:&pos]) { [enckey addObject:[NSString stringWithFormat:@"%o", pos]];
scanInt:
解析十进制字符串中的数字。 stringWithFormat:
同样做它的名字:它创建一个字符串。使用您提供的格式,它会将数字转换为字符串,而不是相反。
因此,您使用scanInt:
来解析十进制数,并使用stringWithFormat:
将其转换为八进制(并将其编码回字符串)。假设,基于sscanf
的代码,输入是八进制的,这与你想要的相反。
此代码肯定会为您提供数字,但它会给您错误的数字,这几乎与sscanf
代码一样糟糕,因为pos
代码会给您全部的零加上崩溃。
您无法使用NSScanner扫描八进制数字。
我也不确定你为什么调用这个变量scanInt:
,因为它似乎不是一个位置。当然,这不是{{1}}给你的。
我能够扫描字符串并提取数字,但我不确定如何在此之后存储到NSData中。
我尝试过使用NSMutableArray和NSData,但没有运气。
这与解决输入数据的问题无关。
我不确定NSArray或C数组(后者可选地包装在NSData中)是否是放置结果的正确位置。这取决于您在解析数字后传递数字的位置。