1

What's an equivalent of the PHP function pack:

pack('H*', '01234567989abcdef' );

in Objective-C?

2

2 Answers 2

2

Assuming that you want the results as an NSData, you can use a function similar to this:

NSData *CreateDataWithHexString(NSString *inputString)
{
    NSUInteger inLength = [inputString length];

    unichar *inCharacters = alloca(sizeof(unichar) * inLength);
    [inputString getCharacters:inCharacters range:NSMakeRange(0, inLength)];

    UInt8 *outBytes = malloc(sizeof(UInt8) * ((inLength / 2) + 1));

    NSInteger i, o = 0;
    UInt8 outByte = 0;
    for (i = 0; i < inLength; i++) {
        UInt8 c = inCharacters[i];
        SInt8 value = -1;

        if      (c >= '0' && c <= '9') value =      (c - '0');
        else if (c >= 'A' && c <= 'F') value = 10 + (c - 'A');
        else if (c >= 'a' && c <= 'f') value = 10 + (c - 'a');            

        if (value >= 0) {
            if (i % 2 == 1) {
                outBytes[o++] = (outByte << 4) | value;
                outByte = 0;
            } else if (i == (inLength - 1)) {
                outBytes[o++] = value << 4;
            } else {
                outByte = value;
            }

        } else {
            if (o != 0) break;
        }        
    }

    return [[NSData alloc] initWithBytesNoCopy:outBytes length:o freeWhenDone:YES];
}
Sign up to request clarification or add additional context in comments.

8 Comments

Thanks this works. There is nothing doing that in the Cocoa libraries already?
Also it looks like you're leaking inCharacters
inCharacters is allocated using alloca, which allocates space on the stack rather than the heap. If you are dealing with large strings and don't feel comfortable advancing the stack pointer that far, you probably want to change inCharacters to a malloc() and free() it before the return.
Oops, didn't see your first reply. It depends on your use case - If the hex value is short enough that you can store it an unsigned int or unsigned long long, there is -[NSScanner scanHexLongLong:]. If you need to do additional extraction, you could use the wscanf() family on -[NSString characters]
This will not work for hex strings with odd-numbers. You need to change the else clause to { outByte = value; if ( i == inLength - 1 ) // this is going to be the last iteration { outBytes[o++] = outByte << 4; } } otherwise you're missing data.
|
1

See the -scanHex... methods of NSScanner.

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.