Cocoa 将八进制的 NSArray/NSString 转换为 NSData?
我正在尝试将这段 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 加密。非常感谢任何帮助,谢谢!
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!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
@Keenan“我希望避免使用 sscanf 和 char* 代替 Cocoa 类”。好吧,你可以做到这一点,但是你希望生产什么?如果您想要一个字节数组作为结果,那么您需要坚持使用
unsigned char[]
,这就引出了为什么要在上进行解析的问题NSString 首先。
这是您的 C 代码的 Objective-C 翻译。请注意,八进制被 Cocoa 视为古老的历史,因此它的解析类仅处理十进制和十六进制,因此您需要编写自己的或使用标准 C 函数(下面的
strtol
)。此示例同时生成一个
unsigned char[]
和一个NSMutableArray
- 选择一个。如果你想接近 Python 的一行,只需将迭代压缩为:
但当然它仍然更长!
@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 onNSString
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 anNSMutableArray
- pick one.If you want to approach the one line of your Python just compress the iteration to:
but it is still longer of course!
快速而肮脏的方法是采用您的原始代码
并添加以下行:
除了您的 sscanf 看起来非常错误。 key 的元素是字符,而不是整数。
The quick and dirty method is to take your original code
And add the following line:
Except that your sscanf looks very wrong. Elements of key are chars, not ints.
由于 CRD 已经很好地向您展示了正确的解决方案,因此我将用我的答案来解释为什么您的解决方案不起作用。
对编译器撒谎永远解决不了问题。
key
是一个unsigned char
数组。在对sscanf
的函数调用中告诉编译器,指向数组的指针是指向int
s 的指针,但这并不能说明问题;每个指向的存储仍然是unsigned char
的存储,仅此而已。其结果是每次尝试在您提供的地址存储一个
int
都会覆盖前一个int
的四分之三。 结果是,sscanf
只不过是用一种更难的方法来完成与memset
相同的事情。我说“多一点”而不是“不再”是有原因的:
sscanf
调用还会在末尾写入sizeof(int) - sizeof(unsigned char)
字节。数组,因此您还破坏了堆栈并为潜在的崩溃做好了准备。scanInt:
以十进制形式解析字符串中的数字。stringWithFormat:
同样如其名称所示:它创建一个字符串。根据您提供的格式,它将数字转换为字符串,而不是相反。因此,您可以使用
scanInt:
解析十进制数字,并使用stringWithFormat:
将其转换为八进制(并将其编码回字符串)。假设基于 sscanf 的代码输入为八进制,这与您想要的相反。这段代码肯定会给你数字,但它也会给你错误的数字,这几乎和 sscanf 代码一样糟糕,它给你全零加上崩溃。
您不能使用 NSScanner 扫描八进制数字。
我也不确定为什么你调用这个变量 pos ,因为它似乎不是一个位置。当然,这不是
scanInt:
为您提供的。请参阅NSData 文档。
这与解析输入数据的问题无关。
我不确定 NSArray 还是 C 数组(后者可选地包装在 NSData 中)是否是放置结果的正确位置。这取决于解析数字后您想要将数字传递到哪里。
As CRD has already done a good job of showing you a correct solution, I'll use my answer to explain why your solutions didn't work.
Lying to the compiler never solves problems.
key
is an array ofunsigned char
s. Telling the compiler, in your function call tosscanf
, that your pointers into the array are pointers toint
s does not make them so; the storage each one points to is still storage for anunsigned char
, and no more.The result of this is that each attempt to store one
int
at an address you provided overwrites three-quarters of the previousint
. The result of that is that thesscanf
amounts to little more than a harder way of doing the same thing as thememset
.I say “little more” and not “no more” for a reason: The
sscanf
call also writessizeof(int) - sizeof(unsigned char)
bytes beyond the end of the array, so you are also smashing the stack and setting up for a potential crash.scanInt:
parses the number from the string in decimal.stringWithFormat:
likewise does what its name says: It creates a string. With the format you gave it, it converts a number to a string, not the other way around.Thus, you use
scanInt:
to parse the number in decimal, andstringWithFormat:
to convert it to octal (and encode it back into a string). Assuming, from thesscanf
-based code, that the input was in octal, this is the opposite of what you want.This code will certainly give you numbers, but it will give you wrong numbers, which is almost as bad as the
sscanf
code that gave you all zeroes plus a crash.You cannot use NSScanner to scan octal numbers.
I'm also not sure why you called this variable
pos
, as it does not appear to be a position. Certainly that's not whatscanInt:
gives you.See the NSData documentation.
That has nothing to do with the problem, which is parsing the input data.
I'm not sure whether an NSArray or a C array (the latter optionally wrapped in an NSData) would be the correct place to put the result. It depends on where you want to pass the numbers once you have them parsed.