24

私は、Objective-C の base 62 変換の実装を探すのに多くの時間を費やしました。これはひどい例だと確信しており、これを行うためのエレガントで超効率的な方法があるに違いありませんが、これは機能します。編集または回答して改善してください! しかし、私はこれを探している人々がうまくいくものを手に入れるのを助けたかった. Objective-C の実装に固有のものは何もないようです。

@implementation Base62Converter

+(int)decode:(NSString*)string
{
    int num = 0;
    NSString * alphabet = @"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";

    for (int i = 0, len = [string length]; i < len; i++)
    {
        NSRange range = [alphabet rangeOfString:[string substringWithRange:NSMakeRange(i,1)]];
        num = num * 62 + range.location;
    }

    return num;
}

+(NSString*)encode:(int)num
{
    NSString * alphabet = @"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
    NSMutableString * precursor = [NSMutableString stringWithCapacity:3];

    while (num > 0)
    {
        [precursor appendString:[alphabet substringWithRange:NSMakeRange( num % 62, 1 )]];
        num /= 62;
    }

    // http://stackoverflow.com/questions/6720191/reverse-nsstring-text
    NSMutableString *reversedString = [NSMutableString stringWithCapacity:[precursor length]];

    [precursor enumerateSubstringsInRange:NSMakeRange(0,[precursor length])
                             options:(NSStringEnumerationReverse |NSStringEnumerationByComposedCharacterSequences)
                          usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) {
                              [reversedString appendString:substring];
                          }];
    return reversedString;
}

@end
4

2 に答える 2

6

encode最終的な文字列を逆にする必要がないように、メソッドを改善できます。

+ (NSString *)encode:(NSUInteger)num
{
    NSString *alphabet = @"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
    NSUInteger base = [alphabet length];
    NSMutableString *result = [NSMutableString string];
    while (num > 0) {
        NSString *digit = [alphabet substringWithRange:NSMakeRange(num % base, 1)];
        [result insertString:digit atIndex:0];
        num /= base;
    }
    return result;
}

もちろん、@ Janoの回答で示唆されているように、これは任意のベースまたはアルファベットに一般化することもできます。

このメソッド(および元のencodeメソッド)は、の空の文字列を返すためnum = 0、このケースを個別に検討する(または単に。に置き換える)ことwhile (num > 0) { ... }ができdo { ... } while (num > 0)ます。


効率を上げるために、すべての中間NSStringオブジェクトを完全に回避し、プレーンなC文字列で作業することができます。

+ (NSString *)encode:(NSUInteger)num
{
    static const char *alphabet = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
    NSUInteger base = 62;

    char result[20]; // sufficient room to encode 2^64 in Base-62
    char *p = result + sizeof(result);

    *--p = 0; // NULL termination
    while (num > 0) {
        *--p = alphabet[num % base];
        num /= base;
    }
    return [NSString stringWithUTF8String:p];
}
于 2013-02-08T22:06:20.930 に答える