I spent much too much time trying to find an implementation for base 62 conversion for Objective-C. I am sure this is a terrible example and there must be an elegant, super-efficient way to do this, but this works, please edit or answer to improve it! But I wanted to help people searching for this to have something that will work. There doesn't appear to be anything specific to be found for an Objective-C implementation.
@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
Your code is fine. If anything, make it more generic. Here is a recursive version for any base (same code):
#import <Foundation/Foundation.h> @interface BaseConversion : NSObject +(NSString*) formatNumber:(NSUInteger)n toBase:(NSUInteger)base; +(NSString*) formatNumber:(NSUInteger)n usingAlphabet:(NSString*)alphabet; @end @implementation BaseConversion // Uses the alphabet length as base. +(NSString*) formatNumber:(NSUInteger)n usingAlphabet:(NSString*)alphabet { NSUInteger base = [alphabet length]; if (n<base){ // direct conversion NSRange range = NSMakeRange(n, 1); return [alphabet substringWithRange:range]; } else { return [NSString stringWithFormat:@"%@%@", // Get the number minus the last digit and do a recursive call. // Note that division between integer drops the decimals, eg: 769/10 = 76 [self formatNumber:n/base usingAlphabet:alphabet], // Get the last digit and perform direct conversion with the result. [alphabet substringWithRange:NSMakeRange(n%base, 1)]]; } } +(NSString*) formatNumber:(NSUInteger)n toBase:(NSUInteger)base { NSString *alphabet = @"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; // 62 digits NSAssert([alphabet length]>=base,@"Not enough characters. Use base %ld or lower.",(unsigned long)[alphabet length]); return [self formatNumber:n usingAlphabet:[alphabet substringWithRange:NSMakeRange (0, base)]]; } @end int main(int argc, char *argv[]) { @autoreleasepool { NSLog(@"%@",[BaseConversion formatNumber:3735928559 toBase:16]); // deadbeef return EXIT_SUCCESS; } }
A Swift 3 version: https://gist.github.com/j4n0/056475333d0ddfe963ac5dc44fa53bf2
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With