How to get a certain bytes length subString from a NSString - ios

Such as I have a NSString is str = #"我就是测试一下" or str = #"我" . And I want to restrict a certain byte length. such as byteLength = 10.
I know the subSrtring is not the str.length=10 How to get a certain bytes length subString from a NSString, thank you

you can use dataUsingEncoding method to get a NSData from NSString. And then use length and bytes property to get the byte length or bytes
Then if the NSData's length > your certain length you should use + (id)dataWithBytes:(const void *)bytes length:(NSUInteger)length; method to get the certain length byte NSData you should be careful that the return NSData may be can not decode by NSString
At last you can use - (id)initWithData:(NSData *)data encoding:(NSStringEncoding)encoding; method to get the result NSString you want
And you can use the code below:
- (NSString *)fetchStringWithOriginalString:(NSString *)originalString withByteLength:(NSUInteger)length
{
NSData* originalData=[originalString dataUsingEncoding:NSUTF8StringEncoding];
const char *originalBytes = originalData.bytes;
//make sure to use a loop to get a not nil string.
//because your certain length data may be not decode by NSString
for (NSUInteger i = length; i > 0; i--) {
#autoreleasepool {
NSData *data = [NSData dataWithBytes:originalBytes length:i];
NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
if (string) {
return string;
}
}
}
return #"";
}
you can call the above method like this :
NSString* originalString= #"我就是测试一下";
NSString *string = [self fetchStringWithOriginalString:originalString withByteLength:10];
NSData* stringData=[string dataUsingEncoding:NSUTF8StringEncoding];
NSLog(#"10 bytes string : %# ; it only %i bytes",string,stringData.length);
The Result :
Be careful:
the - (id)initWithData:(NSData *)data encoding:(NSStringEncoding)encoding; may be return nil
As apple said:the - (id)initWithData:(NSData *)data encoding:(NSStringEncoding)encoding; Return:
An NSString object initialized by converting the bytes in data into
Unicode characters using encoding. The returned object may be
different from the original receiver. Returns nil if the
initialization fails for some reason (for example if data does not
represent valid data for encoding).
So you should use a for loop to get a nearest length data which can decode by NSSting

Use
[str lengthOfBytesUsingEncoding:NSUTF8StringEncoding]

I think this should work:
NSUInteger bytes = [incomingText lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
if (bytes > MAX_TEXT_BYTES) {
int length = [incomingText length];
int cutoffIndex = (int)(MAX_TEXT_BYTES * (length / bytes));
return [incomingText substringToIndex:cutoffIndex];
}

Related

correctly convert hex to base64

I'm trying to get the correct base64 string by encoding a hex string. It works when I use converter websited but my App does not.
NSData* sentData = [combinedHexMessage dataUsingEncoding : NSUTF8StringEncoding];
NSLog (#"%#",sentData);
NSData* sentDataBase64 = [sentData base64EncodedDataWithOptions:0];
NSLog(#"%#",[NSString stringWithUTF8String:[sentDataBase64 bytes]]);
This is my code. combinedHexMessage looks like this in NSLog:
ffd8ffe000104a46494600010101006000600000ffdb004300020101020101020 ...
sentData :
66666438 66666530 30303130 34613436 34393436 30303031 30313031 ...
sentDataBase64 :
ZmZkOGZmZTAwMDEwNGE0NjQ5NDYwMDAxMDEwMTAwNjAwMDYwMDAwMGZmZGIwMDQzM ...
But it should look like:
/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAIBAQIBAQICAgICAgICAwUDAwMDAwYEBAMFB ...
Because this is the string I get after I paste my hex string there:
http://tomeko.net/online_tools/hex_to_base64.php?lang=en
What am I doing wrong?
If you have a hex string that represents an image, you simply want to convert that hex string to a NSData
NSString *hexadecimalString = ...
NSData *data = [hexadecimalString dataFromHexadecimalString];
self.imageView.image = [UIImage imageWithData:data];
Where dataFromHexadecimalString might be defined in a NSString category like so:
#implementation NSString (Hexadecimal)
- (NSData *)dataFromHexadecimalString
{
// in case the hexadecimal string is from `NSData` description method (or `stringWithFormat`), eliminate
// any spaces, `<` or `>` characters
NSString *hexadecimalString = [self stringByReplacingOccurrencesOfString:#"[ <>]" withString:#"" options:NSRegularExpressionSearch range:NSMakeRange(0, [self length])];
NSMutableData * data = [NSMutableData dataWithCapacity:[hexadecimalString length] / 2];
for (NSInteger i = 0; i < [hexadecimalString length]; i += 2) {
NSString *hexChar = [hexadecimalString substringWithRange: NSMakeRange(i, 2)];
int value;
sscanf([hexChar cStringUsingEncoding:NSASCIIStringEncoding], "%x", &value);
uint8_t byte = value;
[data appendBytes:&byte length:1];
}
return data;
}
#end
No base-64 conversion is needed in this process.

Compare NSData with byte sequence?

Note: in other questions they compare a value stored in NSData objects, not its bytes.
I want to perform something like this:
NSData *d = ...;
if (d == "fff1") {
...
}
The only solution I have found:
NSData *d = ...;
NSString *str = [NSString withFormat:#"%#", d];
if ([str isEqualToString:#"<fff1>"] {
...
}
But I don't like that I need to add extra surrounding backets in comparison. Are there better solutions?
For purpose of comparing raw data you use memcmp:
NSData *dataA;
void *someBuffer;
if(memcmp([dataA bytes], someBuffer, dataA.length) == 0) ; //they are the same
Note you should watch that length is not too large for any of the buffers.
EDIT: added NSData procedure:
Or better yet you could convert your string to NSData and do the comparison on the NSData:
NSData *d = ...;
if([d isEqualToData:[NSData dataWithBytes:"fff1" length:sizeof("fff1")]]) {
}

NSString compare returning NSOrderedDescending instead of NSOrderedSame

I am receiving the data in an iPad application from a socket connected.
I am converting the data received to NSString using the method below:
NSString *data = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding].
Then I am creating a substring from the string using the
NSString *substring1 = [data substringFromIndex:length-9]
NSString *substring2 = [data substringFromIndex:length-3]
where length is [data length].
Then I am comparing the substring2 with #"/>" string as below
[substring2 compare:#"/>"]
Here I checked the value of the substring2 while debugging the application the value is #"/>"
but the comparison result is returned as NSOrderedDescending instead of NSOrderedSame.
Can anyone please help?
Your string is having trailing space. The string which you are extracting as length - 3, it must be of length 3.
Now you are comparing it with #"/>" which is having length 2.
You need to do it be below way:
NSString *data = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding].
data = [data stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
Now take the substring and compare.

NSData in base 10 [duplicate]

This question already has answers here:
Printing NSData using NSLog
(5 answers)
Closed 9 years ago.
Is it possible to NSLog NSData in base 10. Basically to see byte array of NSData.
I would like to see output something like this: [51, -55, 55, -54, -110]
You can define a category on NSData to produce a string with decimal data representation, like this:
#interface NSData (DecimalOutput)
-(NSString*)asDecimalString;
#end
#implementation NSData (DecimalOutput)
-(NSString*)asDecimalString {
NSMutableString *res = [NSMutableString string];
[res appendString:#"["];
// Construct an `NSString`, for example by appending decimal representations
// of individual bytes to the output string
const char *p = [self bytes];
NSUInteger len = [self length];
for (NSUInteger i = 0 ; i != len ; i++) {
[res appendFormat:#"%i ", p[i]];
}
[res appendString:#"]"];
return res;
}
#end
Now you can use this to NSLog strings in the new format:
NSLog("Data:%#", [myData asDecimalString]);

How to convert NData populated with hex values to NSString

I have a NSdata object that is populated with a bunch of information thats formated in hex.. I am trying to convert it into its proper string representation but am struggling to have any success.
One thing I have tried is to simply put it into a NSString and then NSLog it with a special character identifier thingy.. forgot the word (%02x), However to do this I am encoding it to NSUTF16.. which i dont want to do.. I mearly want to see exactly whats the data I am getting looks like as a NSString.
The reason I am doing this is because I am having some issues with my encoding later on in my code and im not sure if its because the data I am receiving is incorrect or me stuffing it up at some point when I am handling it.
Any help would be appreciated.
You can get a string representation of your NSData like so:
NSData *data = (your data)
NSString *string = [NSString stringWithCString:[data bytes] encoding:NSUTF8StringEncoding];
Does that answer your question?
Maybe I haven't understood, but something like this:
NSData *yourData;
NSLog(#"%#", [yourData description]);
doesn't fit your need?
Give this a try -
-(NSString*)hexToString:(NSData*)data{
NSString *hexString = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
if (([hexString length] % 2) != 0)
return nil;
NSMutableString *string = [NSMutableString string];
for (NSInteger i = 0; i < [hexString length]; i += 2) {
NSString *hex = [hexString substringWithRange:NSMakeRange(i, 2)];
NSInteger decimalValue = 0;
sscanf([hex UTF8String], "%x", &decimalValue);
[string appendFormat:#"%d", decimalValue];
}
return string;
}

Resources