Что является Objective-C эквивалентом C# HttpServerUtility.UrlTokenDecode?

В Objective-C, как я могу декодировать строку, которая была закодирована в C#, используя HttpServerUtility.UrlTokenEncode?

В Java я смог использовать этот метод, предложенный @Gideon.

Я попытался преобразовать этот метод из Java в Objective-C, и это то, что я получил до сих пор.

- (NSData *)URLTokenDecode:(NSString *)input {

NSData *result;
NSUInteger len = [input length];
NSUInteger numPadChars = (int)[input characterAtIndex:len-1] - (int)'0';

if(numPadChars >10)
    return nil;

char base64Chars[len - 1 + numPadChars];

for(int iter = 0; iter < len-1 ; iter++){
    char c = [input characterAtIndex:iter];
    switch (c) {
        case '-':
            base64Chars[iter] = '+';
            break;

        case '_':
            base64Chars[iter] = '/';
            break;

        default:
            base64Chars[iter] = c;
            break;
    }
}

for(int iter = len-1; iter < strlen(base64Chars); iter++){
    base64Chars[iter] = '=';
}

NSString* assembledString = [NSString stringWithCString:base64Chars encoding:NSASCIIStringEncoding];
result = [[NSData alloc] initWithBase64EncodedString:assembledString options:0];

return result;
}

результат должен быть NSData который затем может быть использован для заполнения ImageView с помощью [UIImage imageWithData:result];

Я попытался отладить этот метод с теми же данными из метода Java, но по какой-то причине результат всегда становится равным нулю.

Я заметил в версии Objective C размер массива base64Chars strlen(base64Chars) всегда на единицу меньше версии Java base64Chars.lengthЯ попытался обойти это, но это не сработало.

Заранее благодарю за любую помощь.

2 ответа

Решение

Как альтернативный подход. Я сделал весь метод более дружественным к Objective-C.

NSData *URLTokenDecode(NSString *token)
{
    if (token.length == 0) return nil;

    // The last character in the token is the number of padding characters.
    NSUInteger numberOfPaddingCharacters = [token characterAtIndex:token.length - 1] - '0';
    if (numberOfPaddingCharacters > 10) return nil;

    // The Base64 string is the token without the last character.
    NSString *base64 = [token substringWithRange:NSMakeRange(0, token.length - 1)];

    // '-'s are '+'s and '_'s are '/'s.
    base64 = [base64 stringByReplacingOccurrencesOfString:@"-" withString:@"+"];
    base64 = [base64 stringByReplacingOccurrencesOfString:@"_" withString:@"/"];

    // Pad the Base64 string out with '='s
    NSUInteger paddedLength = base64.length + numberOfPaddingCharacters;
    base64 = [base64 stringByPaddingToLength:paddedLength withString:@"=" startingAtIndex:0];

    NSData *result = [[NSData alloc] initWithBase64EncodedString:base64 options:kNilOptions];
    return result;
}

Вы используете strlen() для получения длины, это уже длина заполнения, а не размер base64Chars или len - 1 + numPadChars в реализации Java. Итак = заполнение может не заполнять.

Вы можете попробовать мой фиксированный метод:

- (NSData *)UrlTokenDecode:(NSString *)input {

NSData *result;
NSUInteger len = [input length];
NSUInteger numPadChars = (int)[input characterAtIndex:len-1] - (int)'0';

if(numPadChars >10)
    return nil;

char* base64Chars = malloc(len+numPadChars); // no -1 because need a '\0' end
memset(base64Chars, 0, len+numPadChars);

for(int iter = 0 ; iter < len-1 ; iter++){
    char myChar = [input characterAtIndex:iter];
    switch (myChar) {
        case '-':
            base64Chars[iter] = '+';
            break;

        case '_':
            base64Chars[iter] = '/';
            break;

        default:
            base64Chars[iter] = myChar;
            break;
    }
}

for(int iter = len-1 ; iter < len+numPadChars-1; iter++){
    base64Chars[iter] = '=';
}

NSString* assembledString = [NSString stringWithCString:base64Chars encoding:NSASCIIStringEncoding];
result = [[NSData alloc] initWithBase64EncodedString:assembledString options:0];
free(base64Chars);

return result;
}
Другие вопросы по тегам