Какао Конвертировать NSArray / NSString восьмеричных чисел в NSData? - PullRequest
0 голосов
/ 11 марта 2011

Я пытаюсь преобразовать этот бит кода C в Какао, и я пытаюсь понять, как.

  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;
    }
  }

В основном, пытаясь преобразовать ключ DES ascii в строку, чтобы использовать для Triple DESшифрование.Спасибо за любую помощь, спасибо!

Ответы [ 3 ]

1 голос
/ 12 марта 2011

@ Кинэн "Я надеялся избежать использования sscanf и char * вместо классов Какао".Ну, вы можете сделать это, но что вы надеетесь произвести?Если вы хотите получить байтовый массив в качестве результата, тогда вам нужно придерживаться unsigned char[], и возникает вопрос, почему вы сначала выполните синтаксический анализ NSString.

Вот перевод Objective-C вашего C-кода.Обратите внимание, что восьмеричное восходит к Какао как древняя история, поэтому его классы синтаксического анализа имеют дело только с десятичной и шестнадцатеричной кодами, поэтому вам нужно написать свою собственную или использовать стандартную функцию 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)]]; }

, ноэто еще дольше конечно!

0 голосов
/ 12 марта 2011

Поскольку 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 s.Указание компилятору при вызове функции на sscanf, что ваши указатели на массив являются указателями на int s, не делает их такими;хранилище, на которое указывает каждый из них, по-прежнему является хранилищем для 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) правильным местом для размещения результата.Это зависит от того, куда вы хотите передать числа после их анализа.

0 голосов
/ 11 марта 2011

Быстрый и грязный метод - взять ваш оригинальный код

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 выглядит очень неправильно.Элементами ключа являются символы, а не целые.

...