1

How do I convert binary data to hex value in obj-c? Example:

1111 = F, 
1110 = E, 
0001 = 1, 
0011 = 3.

I have a NSString of 10010101010011110110110011010111, and i want to convert it to hex value. Currently I'm doing in a manual way. Which is,

-(NSString*)convertToHex:(NSString*)hexString

{ NSMutableString *convertingString = [[NSMutableString alloc] init];

for (int x = 0; x < ([hexString length]/4); x++) {

    int a = 0;
    int b = 0; 
    int c = 0;
    int d = 0;

    NSString *A = [NSString stringWithFormat:@"%c", [hexString characterAtIndex:(x)]];
    NSString *B = [NSString stringWithFormat:@"%c", [hexString characterAtIndex:(x*4+1)]];
    NSString *C = [NSString stringWithFormat:@"%c", [hexString characterAtIndex:(x*4+2)]];
    NSString *D = [NSString stringWithFormat:@"%c", [hexString characterAtIndex:(x*4+3)]];


    if ([A isEqualToString:@"1"]) { a = 8;}

    if ([B isEqualToString:@"1"]) { b = 4;}

    if ([C isEqualToString:@"1"]) { c = 2;}

    if ([D isEqualToString:@"1"]) { d = 1;}

    int total = a + b + c + d;

    if (total < 10) { [convertingString appendFormat:@"%i",total]; }
    else if (total == 10) { [convertingString appendString:@"A"]; }
    else if (total == 11) { [convertingString appendString:@"B"]; }
    else if (total == 12) { [convertingString appendString:@"C"]; }
    else if (total == 13) { [convertingString appendString:@"D"]; }
    else if (total == 14) { [convertingString appendString:@"E"]; }  
    else if (total == 15) { [convertingString appendString:@"F"]; } 

}

NSString *convertedHexString = convertingString;
return [convertedHexString autorelease];
[convertingString release];

}

Anyone have better suggestion? This is taking too long. Thanks in advance.

2

3 Answers 3

1

I have never been much of a C hacker myself, but a problem like this is perfect for C, so here is my modest proposal - coded as test code to run on the Mac, but you should be able to copy the relevant bits out to use under iOS:

#import <Foundation/Foundation.h>

int main(int argc, char *argv[]) {
    NSAutoreleasePool *p = [[NSAutoreleasePool alloc] init];

    NSString *str = @"10010101010011110110110011010111";

    char* cstr = [str cStringUsingEncoding: NSASCIIStringEncoding];

    NSUInteger len = strlen(cstr);

    char* lastChar = cstr + len - 1;
    NSUInteger curVal = 1;

    NSUInteger result = 0;

    while (lastChar >= cstr) {

        if (*lastChar == '1')
        {
            result += curVal;
        }
        /*
        else 
        {
            // Optionally add checks for correct characters here
        }
        */

        lastChar--;
        curVal <<= 1;
    }

    NSString *resultStr = [NSString stringWithFormat: @"%x", result];

    NSLog(@"Result: %@", resultStr);

    [p release];
}

It seems to work, but I am sure that there is still room for improvement.

Sign up to request clarification or add additional context in comments.

Comments

1
@interface bin2hex : NSObject
+(NSString *)convertBin:(NSString *)bin;
@end
@implementation bin2hex
+(NSString*)convertBin:(NSString *)bin
{
    if ([bin length] > 16) {

        NSMutableArray *bins = [NSMutableArray array];
        for (int i = 0;i < [bin length]; i += 16) {
            [bins addObject:[bin substringWithRange:NSMakeRange(i, 16)]];
        }

        NSMutableString *ret = [NSMutableString string];
        for (NSString *abin in bins) {
            [ret appendString:[bin2hex convertBin:abin]];
        }

        return ret;

    } else {
        int value = 0;
        for (int i = 0; i < [bin length]; i++) {
            value += pow(2,i)*[[bin substringWithRange:NSMakeRange([bin length]-1-i, 1)] intValue];
        }
        return [NSString stringWithFormat:@"%X", value];
    }
}

@end

int main (int argc, const char * argv[])
{

    @autoreleasepool {

        // insert code here...
        NSLog(@"0x%@",[bin2hex convertBin:@"10010101010011110110110011010111"]);

    }
    return 0;
}

I get the result of 0x954F6CD7 for 10010101010011110110110011010111 and it seems to be instant

3 Comments

thanks! I have a question here, why do you "chop" it into 16 binary character first and later only do the work with 4 binary character?
because int can only handle 16 bits
you could switch it up to a long which can hold either 32 or 64 bits depending on your system
0

Maybe easiest would be to setup a NSDictionary for quick lookups?

[NSDictionary dictionaryWithObjects...]

since it is a limited number of entries.

"0000" -> 0
...
"1111" -> F

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.