I have made a web service that gets an integer as a unique identifier for a Phone. Later, i realised that an iPhone UID is an NSstring in that format: 5DE31FA12-XXXXX-XXXXX-XXXXXXX. So i would like to convert this value to an integer.
Here is the way i get the UID in a NSString format.
CFUUIDRef theUUID = CFUUIDCreate(NULL);
CFStringRef string = CFUUIDCreateString(NULL, theUUID);
CFRelease(theUUID);
NSString *theUID = (NSString *)string;
How can i convert NSString *theUID into an integer value, so as to send it to the webservice?
EDIT: As CocoaFu correctly mentioned , it is impossible to fit that value in an int. Could I somehow convert it to an NSString with a format like "ddddddddddddddddddddddddddd" (where d = 0-9) so as to hash it and then send it? It is impossible to change the webservice now.
The largest integer is 8 bytes or 64 bits. The UUID you show has 26 hex characters which is 104 bits. It just won't fit in an integer. Use the string.
CFUUIDCreate returns a string with 32 hex characters, that is 128 bits or 16 bytes. Ignore the '-' characters, they are just for human readability. Here is an example from
CFUUIDCreate: BDFC3FE6-3A5E-48C0-B18D-E42B8E275428
UDID won't fit in an int. The format you have listed is what the simulator gives you. Device UDID is 40-characters long alpha-numeric.
Related
I made a request to facebook API using facebook SDK to get user basic data. Everything works ok, but when I try to pass the facebook ID as a NSInteger number the returned number is wrong.
The facebook ID is: 100001778401161
But after convert the number to NSInteger the number returned is: 2054848393
How can I store the facebook ID on a NSInteger variable?
My current code is:
NSLog(#"The ID: %ld", (long)[[user objectForKey:#"id"] intValue])
Thanks.
Such a number needs 64 bits, NSInteger does only cover 32 bits (and with positive numbers only 31 bits). Try using long long values:
NSLog(#"The ID: %lld", [[user objectForKey:#"id"] longLongValue]);
you can use also NSNumber if you need to store it as an object somehow:
NSNumber *number=[NSNumber numberWithLongLong:[user[#"id"] longLongValue]];
NSInteger (and long) is a 32-bit value and the ID you are using exceeds the maximum value that it can hold, so it overflows. You could try:
long long facebookId = [[user objectForKey: #"id"] longLongValue];
NSLog(#"The ID: %lld", facebookId);
I don't know anything about the facebook API so you might want to make sure that the ID is guaranteed to be numeric over time. If, for example, they specify somewhere that the ID is a string, you should match that even if they seem to always be numeric.
You can't store the number larger than 2 ^ 31 in NSInteger type.
If you want to store the one larger, then you can use NSDecimalNumber object instead.
Or you can use unsigned long long type.
NSDecimalNumber *number = [NSDecimalNumber decimalNumberWithString:[user objectForKey:#"id"]];
NSLog(#"Number: %#", number);
unsigned long long ullValue = strtoull([user objectForKey:#"id"], NULL, 0);
NSLog(#"Number: %llu", ullValue);
Hope this will help you!
I have a NSString with me. This NSString is obtained from a Voice engine. The voice input is converted to native NSString.
See the following string:
"Set heat to thirty two degree"
Is there any way to get this converted to
"Set heat to 32 degree"
If there are some third party library that does this conversion, it would be really helpful. Otherwise I will have to create a complex logic to get this done it seems.
And that's where a forgotten NSNumberFormatter can show what it's capable of doing.
After you parsed your input string (using regular expression magic or NSString's componentsSeparatedByString:, I'll not be discussing that step) and obtained the spell-out number, you can use NSNumberFormatter's NSNumberFormatterSpellOutStyle to quickly convert your string into a number:
NSString *obtainedDegreesString = #"thirty-two";
NSNumberFormatter *spellOutFormatter = [[NSNumberFormatter alloc] init];
[spellOutFormatter setLocale:[NSLocale currentLocale]]; // or whatever locale you want
[spellOutFormatter setNumberStyle:NSNumberFormatterSpellOutStyle];
NSNumber *degreesNumber = [spellOutFormatter numberFromString:obtainedDegreesString];
NSLog(#"%d", degreesNumber.intValue); // logs 32
But warning - you have to convert strings like "thirty two" to "thirty-two" (the correct English numerals) for your formatter to work - passing "thirty two" results in 3002! Your users probably don't want to burn in 3002 degrees :P You can achieve that using another regular expression, I suppose.
There's a special NSString initWithData method for grabbing bits and converting them into string. However, I haven't found that in NSNumber class ref. Currently, I'm getting raw data (bytes) from a server in NSData format. I know how to do that in C, using memcpy and int pointers. But I am curious about what the convenience methods are for doing that straight from NSData. No conversion is needed. For example, I'm getting 00000010 byte, and I need to turn that into NSNumber of value 2, or NSInteger.
NSData is just a bucket for bytes and has no knowledge of the data contained therein. NSString's initWithData:encoding: method is a reciprocal (it does the opposite) of this method:
- (NSData *)dataUsingEncoding:(NSStringEncoding)encoding
Therefore, to answer your question fully, it's important to know how your numbers were originally coerced into an NSData object. Once you know the encoding function, the search is for the reciprocal function.
From what you've included in the question, there may be a number of different solutions. However, you'll probably be able to use something along the following lines to convert into a usable numeric format using getBytes:length: on your NSData object. For e.g.
NSUInteger decodedInteger;
[myDataObject getBytes:&decodedInteger length:sizeof(decodedInteger)];
You can change the type of decodedInteger to whatever is appropriate for the bytes in your NSData object.
Try this:
NSNumber *num = [NSKeyedUnarchiver unarchiveObjectWithData:numberAsNSData];
Edit:
As pointed out by Matthias Bauch this will not work in your case. This only works if your NSNumber object was archived into NSData objects.
NSString to the rescue:
const unsigned char *bytes = [serverData bytes];
NSInteger aValue = [NSString stringWithFormat:#"%2x", bytes[0]].integerValue;
The docs warn about using NSScanner for localized decimal numbers, but that's of no concern in this case.
Here is the answer
//Integer to NSData
+(NSData *) IntToNSData:(NSInteger)data
{
Byte *byteData = (Byte*)malloc(4);
byteData[3] = data & 0xff;
byteData[2] = (data & 0xff00) >> 8;
byteData[1] = (data & 0xff0000) >> 16;
byteData[0] = (data & 0xff000000) >> 24;
NSData * result = [NSData dataWithBytes:byteData length:4];
NSLog(#"result=%#",result);
return (NSData*)result;
}
refer https://stackoverflow.com/a/20497490/562812 for more detail
I want to make the UDID of a iOS device to less than or equal to 15 characters.
I am porting a Symbian based client-server software to iOS. The server side uses IMEI (15 digits)to id a client phone. Now on iOS, UDID is too long(40 hex digits). As I want to minimize the change of server program or DB, I need to store the UDID in a varchar(15).
So it's there any way to make the UDID shorter but still unique enlough. It could be much better if I can also get the UDID from the shorted string.
You could convert the hex digits into 20 Latin-1 characters (≤0xff) or 10 Unicode BMP characters (≤0xffff).
If that varchar(15) can accept Unicode BMP characters, then we are done.
Otherwise, you could chop the last 5 characters from that 20 Latin-1 characters. The UDID is in fact a SHA-1 hash of some device-unique values, which can be considered quite random and the digits are uniformly distributed. Therefore, with 15 Latin-1 characters the reduced UDID should be able to represent 25615 ~ 1036 devices, which is much more than enough.
In fact, even if you just take 15 hex characters from the UDID it could already represent ~ 1018 devices.
Note that the last 2 methods are lossy, i.e. there is no way you could get the complete UDID from the 15 characters.
I just wrote this gist -> https://gist.github.com/3996097
What do you think about a CFUUID + sha1 + substring + random uppercase ?
//Get a random hash (Generated from CFUUID+sha1)
NSString *hash = [NSString sha1:[NSString getUUID]];
//Shorten the sha1
NSString *short_random_id = [hash substringFromIndex:[hash length]-10];
//Random uppercase / lowercase the id
NSMutableString *random_id_final = [NSMutableString string];
for (NSUInteger i = 0; i < [short_random_id length]; i++)
{
NSString *substring = [short_random_id substringWithRange:NSMakeRange(i, 1)];
[random_id_final appendString:(rand() % 2) ? [substring lowercaseString] : [substring uppercaseString]];
}
Can someone help me ? I have a NSString with #"12.34" and I want to convert it into a NSString with the same float number but in single precision 32bits binary floating-point format IEEE-754 : like #"\x41\x45\x70\xa4" (with hexa characters) or #"AEp¤"...
I'm sure it's something easy but after many hours of reading the doc without finding a solution...
Thank you !
As Yuji mentioned, it's not a good idea to encode an arbitrary byte sequence into an NSString(although it can contain null bytes), as encoding transformations can(and probably WILL) destroy your byte sequence. If you want access to the raw bytes of a float, you may want to consider storing them as an NSData object(though I suggest you think through your reasons for wanting this first). To do this:
NSString *string = #"10.23";
float myFloat = [string floatValue];
NSData *myData = [[NSData alloc] initWithBytes:&myFloat length:sizeof(myFloat)];
If you want to get the raw bytes of a float, you could cast it, like so:
NSString *str = #"12.34";
float flt = [str floatValue];
unsigned char *bytes = (unsigned char *)&flt;
printf("Bytes: %x %x %x %x\n", bytes[0], bytes[1], bytes[2], bytes[3]);
However the order in which these bytes are stored in the array depends on the machine. (See http://en.wikipedia.org/wiki/Endianness). For example, on my Intel iMac it prints: "Bytes: a4 70 45 41".
To make a new NSString from an array of bytes you can use initWithBytes:length:encoding: