I have an 8 bit Hex Value like: "FB" (-5). Now I need an signed integer value for this hex. The NSScanner don't work on this place, because you need an 4 Byte hex value, to get it negative. Before I start some bit manipulation, maybe someone of you know the better way to do that?
Type casting is not safe but you really need it.
NSString *tempNumber = #"FB";
NSScanner *scanner = [NSScanner scannerWithString:tempNumber];
unsigned int temp;
[scanner scanHexInt:&temp];
int actualInt = (char)temp; //why char because you have 8 bit integer
NSLog(#"%#:%d:%d",tempNumber, temp, actualInt);
Console output: FB:251:-5
Related
I would like to get a dec value from a 20 bytes Hex-encoded string, and I coded as following:
//str is a 20 bytes hex string. For example, the variable str = (__NSCFString *) #"3EDB616369C275F09E03EC2E6BDF85F888851333"
unsigned int value = 0;
NNscanner *scanner = [NSScanner scannerWithString:str];
[scanner scanHexInt:&value];
But, however, I dont know why the line scanHexInt returns No and the variable value is not updated.
My goal is to compare two hex strings and determine which number is higher. I assume I need to convert those hex strings to integers to be able to compare them mathematically, but the conversion to unsigned isn't working. Here's what I've tried:
NSString *firstHex = #"35c1f029684fe";
NSString *secondHex = #"35c1f029684ff";
unsigned first = 0;
unsigned second = 0;
NSScanner *firstScanner = [NSScanner scannerWithString:firstHex];
NSScanner *secondScanner = [NSScanner scannerWithString:secondHex];
[firstScanner scanHexInt:&first];
[secondScanner scanHexInt:&second];
NSLog(#"First: %d",first);
NSLog(#"Second: %d",second);
But the log output gives me:
First: -1
Second: -1
I can't figure out what I'm doing wrong. Am I using NSScanner correctly here? Thanks in advance.
Your hex numbers are 13 digits long - 52 binary bits. This is longer than 32 bits, use long long variables and scanHexLongLong: instead.
For the sake of completeness, here's the working code using the advice from the above answer:
NSString *firstHex = #"35c1f029684fe";
NSString *secondHex = #"35c1f029684ff";
unsigned long long first = 0;
unsigned long long second = 0;
NSScanner *firstScanner = [NSScanner scannerWithString:firstHex];
NSScanner *secondScanner = [NSScanner scannerWithString:secondHex];
[firstScanner scanHexLongLong:&first];
[secondScanner scanHexLongLong:&second];
NSLog(#"First: %llu",first);
NSLog(#"Second: %llu",second);
if(first > second){
NSLog(#"First is greater");
}else{
NSLog(#"Second is greater");
}
it must be faster to just find out which one is larger as a string:
the longer string is bigger (ignoring leading 0's)
if they are the same then you can convert each char and compare, Repeat for each char...
Try this:
unsigned long long int N; = 23229877463LL;
NSString* s = [NSString stringWithFormat:#"dec:%qi, hex:%qX",N,N];
NSLog(#"output: %#",s);
output: dec:23229877460, hex:689BCCD400000005
What's up with the 00000005??? In mySQL, hex(23229877460) = 5689BCCD4. Also, every other language seems to do this correctly. A 16 digit long hex is like 4 gazillion (16^16), right?
How can I get objective-c to format hex numbers that other languages can understand?
After fixing the spurious ; to yield:
unsigned long long int N = 23229877463LL;
NSString* s = [NSString stringWithFormat:#"dec:%qi, hex:%qX",N,N];
NSLog(#"output: %#",s);
The code works exactly as expected:
2011-01-09 10:46:16.236 dfjkdfkjfdjkfd[25716:a0f] output: dec:23229877463, hex:5689BCCD7
There is something else wrong. You'll need to post more code. The line used to compile the file would probably be helpful, too.
And for giggles:
unsigned long long int N = 23229877460LL;
NSString* s = [NSString stringWithFormat:#"dec:%qi, hex:%qX",N,N];
2011-01-09 10:49:10.425 dfjkdfkjfdjkfd[25755:a0f] output: dec:23229877460, hex:5689BCCD4
Are there any Cocoa classes that will help me convert a hex value in a NSString like 0x12FA to a long or NSNumber? It doesn't look like any of the classes like NSNumberFormatter support hex numbers.
Thanks,
Hua-Ying
Here's a short example of how you would do it using NSScanner:
NSString* pString = #"0xDEADBABE";
NSScanner* pScanner = [NSScanner scannerWithString: pString];
unsigned int iValue;
[pScanner scanHexInt: &iValue];
See NSScanner's scanHex...: methods. That'll get you the primitive that you can wrap in an NSNumber.
here is the other way conversion, a long long int to hex string.
first the hex to long long.
NSString* pString = #"ffffb382ddfe";
NSScanner* pScanner = [NSScanner scannerWithString: pString];
unsigned long long iValue2;
[pScanner scanHexLongLong: &iValue2];
NSLog(#"iValue2 = %lld", iValue2);
and the other way, longlong to hex string...
NSNumber *number;
NSString *hexString;
number = [NSNumber numberWithLongLong:iValue2];
hexString = [NSString stringWithFormat:#"%qx", [number longLongValue]];
NSLog(#"hexString = %#", hexString);
I'm trying to use a function that has the following signature to sign a HTTP request:
extern void hmac_sha1(const unsigned char *inText, int inTextLength, unsigned char* inKey, const unsigned int inKeyLength, unsigned char *outDigest);
And this is the method I wrote to use it:
- (NSString *)sign: (NSString *)stringToSign {
NSString *secretKey = #"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
const unsigned char *inText = (unsigned char *)[stringToSign UTF8String];
int inTextLength = [stringToSign length];
unsigned char *inKey = (unsigned char *)[secretKey UTF8String];
const unsigned int inKeyLength = (unsigned int)[secretKey length];
unsigned char *outDigest;
hmac_sha1(inText, inTextLength, inKey, inKeyLength, outDigest);
NSString *output = [NSString stringWithUTF8String:(const char *)outDigest];
return output;
}
The problem is I'm sure this is not the way I'm supposed to do this casting, as inside this hmac_sha1 function I get a EXC_BAD_ACCESS exception.
Since I am new to Objective-C and have close to no experience in C (surprise!) I don't really know what to search for. Any tips on how I can start solving this?
Thanks in advance!
BTW, I got the reference for this function here in stackoverflow.
It looks like the problem is not with the casting, but with outDigest. The fifth argument to hmac_sha1 should point to an already allocated buffer of size 20 bytes (I think).
If you change the line that says
unsigned char *outDigest;
to say
#define HMACSHA1_DIGEST_SIZE 20
void *outDigest = malloc(HMACSHA1_DIGEST_SIZE);
That should get you past the crash inside hmac_sha1.
Then you've got the problem of converting the data at outDigest into an NSString. It looks like hmac_sha1 will put 20 bytes of random-looking data at outDigest, and not a null terminated UTF-8 string, so stringWithUTF8String: won't work. You might want to use something like this instead if you have to return an NSString:
NSString *output = [[NSString alloc] initWithBytesNoCopy:outDigest
length:HMACSHA1_DIGEST_SIZE
encoding:NSASCIIStringEncoding
freeWhenDone:YES];
I don't think NSString is really the right type for the digest, so it might be worth changing your method to return an NSData if you can.
This wasn't part of your question but it's a bug nonetheless, you shouldn't use -length to get the byte count of an UTF8 string. That method returns the number of Unicode characters in the string, not the number of bytes. What you want is -lengthOfBytesUsingEncoding:.
NSUInteger byteCount = [stringToSign lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
Also be aware that the result does not account for a terminating NULL character.
Are you sure you don't need to allocate some memory for outDigest before calling hmac_sha1? Since you pass in a pointer, rather than a pointer to a pointer, there's no way that the memory can be allocated inside the routine.