Re: Hex to NSString or NSData
Re: Hex to NSString or NSData
- Subject: Re: Hex to NSString or NSData
- From: "Mr. Gecko" <email@hidden>
- Date: Sat, 9 May 2009 22:57:40 -0500
I was able to get done what I wanted with this.
int char2hex(unichar c) {
switch (c) {
case '0' ... '9': return c - '0';
case 'a' ... 'f': return c - 'a' + 10;
case 'A' ... 'F': return c - 'A' + 10;
default: return -1;
}
}
- (NSData *)hexToData {
unsigned stringIndex=0, resultIndex=0, max=[self length];
NSMutableData* result = [NSMutableData dataWithLength:(max + 1)/2];
unsigned char* bytes = [result mutableBytes];
unsigned num_nibbles = 0;
unsigned char byte_value = 0;
for (stringIndex = 0; stringIndex < max; stringIndex++) {
int val = char2hex([self characterAtIndex:stringIndex]);
if (val < 0) continue;
num_nibbles++;
byte_value = byte_value * 16 + (unsigned char)val;
if (! (num_nibbles % 2)) {
bytes[resultIndex++] = byte_value;
byte_value = 0;
}
}
//final nibble
if (num_nibbles % 2) {
bytes[resultIndex++] = byte_value;
byte_value = 0;
}
[result setLength:resultIndex];
return result;
}
I had to go through open source hex editors to find out.
Thanks for the help,
Mr. Gecko
On May 9, 2009, at 3:43 AM, Gwynne Raskind wrote:
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