Re: Hex to NSString or NSData
Re: Hex to NSString or NSData
- Subject: Re: Hex to NSString or NSData
- From: Gwynne Raskind <email@hidden>
- Date: Sat, 9 May 2009 04:43:24 -0400
On May 8, 2009, at 11:34 PM, Mr. Gecko wrote:
And how could that make @"68656c6c6f" into @"hello"?
Thinking this will help you understand what I'm trying to do...
On May 8, 2009, at 10:23 PM, Jerry Krinock wrote:
On 2009 May 08, at 20:16, Mr. Gecko wrote:
Hello, I have a string with hex and I want to ether make it into a
NSData or NSString. How might I do that.
-[NSString initWithBytes:length:encoding:]
If you need to scan 32-bit or 64-bit hex numbers, check out:
<http://developer.apple.com/DOCUMENTATION/Cocoa/Reference/Foundation/Classes/NSScanner_Class/Reference/Reference.html
>
DISCLAIMER: ALL CODE WRITTEN IN MAIL AND UNTESTED (Well, that's not
quite true, I did test the long hex string function out of
curiosity :) ).
Also note: All this code does simplistic error handling by throwing
exceptions. You may want to just return nils or zeroes on failure.
- (uint32_t)unsignedIntFromHexString:(NSString *)str
{
NSScanner *scanner = [NSScanner scannerWithString:str];
uint32_t result = 0;
if (![scanner scanHexInt:&result])
{
[NSException raise:NSInvalidArgumentException format:@"No hex number
found in %@.", str];
}
return result;
}
- (uint64_t)unsignedLongLongFromHexString:(NSString *)str
{
NSScanner *scanner = [NSScanner scannerWithString:str];
uint64_t result = 0;
if (![scanner scanHexLongLong:&result])
{
[NSException raise:NSInvalidArgumentException format:@"No hex number
found in %@.", str];
}
return result;
}
If you need to scan arbitarily-sized hex strings, you'll need
something more complex:
char hexCharToNibble(char nibble)
{
// 0 - 9
if (nibble >= '0' && nibble <= '9')
return (nibble - '0') & 0x0F;
// A - F
else if (nibble >= 'A' && nibble <= 'F')
return (nibble - 'A' + 10) & 0x0F;
// a - f
else if (nibble >= 'a' && nibble <= 'f')
return (nibble - 'a' + 10) & 0x0F;
// Not a hex digit
else
[NSException raise:NSInvalidArgumentException format:@"Character %c
not a hex digit.", nibble];
return 0; // keep compiler happy
}
char hexCharsToByte(char highNibble, char lowNibble)
{
return (hexCharToNibble(highNibble) << 4) | hexCharToNibble(lowNibble);
}
- (NSString *)interpretHexString:(NSString *)str asEncoding:
(NSStringEncoding)encoding
{
// Get the ASCII data out of the string - hexadecimal numbers are
expressed in pure ASCII
NSData *asciiData = [str dataUsingEncoding:NSASCIIStringEncoding
allowLossyConversion:YES];
const char *chars = (char *)[asciiData bytes]; // chars is NOT NULL-
terminated!
if (([asciiData length] % 2) != 0)
{
// There were an odd number of hex characters in the source string.
return nil;
}
// Set up data storage for the raw bytes we interpret
NSMutableData *dataInEncoding = [NSMutableData dataWithLength:
[asciiData length] / 2];
char *dataChars = [dataInEncoding mutableBytes];
// Loop over the ASCII numbers
for (NSUInteger i = 0; i < [asciiData length]; i += 2)
{
// Interpret each pair of hexadecimal characters into a byte.
*dataChars++ = hexCharsToByte(chars[i], chars[i + 1]);
}
// Create an NSString from the interpreted bytes, using the passed
encoding.
// NSString will return nil (or throw an exception) if the bytes we
parsed can't be
// represented in the given encoding.
return [[[NSString alloc] initWithData:dataInEncoding
encoding:encoding] autorelease];
}
It's very likely there's a faster/better/cleaner/whatever way to do
this, but this does work :).
-- Gwynne, Daughter of the Code
"This whole world is an asylum for the incurable."
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden