0

我正在尝试将这段 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 密钥转换为字符串以用于三重 DES 加密。非常感谢任何帮助,谢谢!

4

3 回答 3

1

@Keenan“我希望避免使用 sscanf 和 char* 代替 Cocoa 类”。好吧,你可以做到这一点,但你希望生产什么?如果你想要一个字节数组作为结果,那么你需要坚持unsigned char[],这引出了一个问题,为什么你首先要进行解析NSString

这是您的 C 代码的 Objective-C 翻译。请注意,八进制被 Cocoa 视为古老的历史,因此其解析类仅处理十进制和十六进制,因此您需要编写自己的或使用标准 C 函数(strtol如下)。

此示例同时生成 aunsigned 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)]]; }

但当然还是更长!

于 2011-03-11T23:19:31.637 回答
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 看起来非常错误。key 的元素是字符,而不是整数。

于 2011-03-11T15:42:42.090 回答
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 chars 的数组。在对 的函数调用中告诉编译器sscanf您指向数组的指针是指向ints 的指针并不会使它们如此;每个人指向的存储空间仍然是存储空间,仅此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给你全零加上崩溃的代码一样糟糕。

您不能使用 NSScanner 扫描八进制数。

我也不确定你为什么调用这个变量pos,因为它似乎不是一个位置。当然,这不是scanInt:给你的。

我能够扫描字符串并提取数字,但我不确定之后如何存储到 NSData 中。

请参阅NSData 文档

我试过使用 NSMutableArray 和 NSData 但没有运气。

这与解析输入数据的问题无关。

我不确定 NSArray 或 C 数组(后者可选地包裹在 NSData 中)是否是放置结果的正确位置。这取决于您在解析数字后要将数字传递到哪里。

于 2011-03-12T07:01:31.393 回答