APDU response read Binary to Objective-C String - ios

unsigned char get_cplc_command2[] = {0x00, 0xA4, 0x00, 0x00, 0x02, 0x02, 0x03};
receive_length = sizeof(receive_buffer);
ret = SCardTransmit(card,
&sendPCI,
get_cplc_command2,
sizeof(get_cplc_command2),
NULL,
receive_buffer,
&receive_length);
LOG(#"SCardTransmit 0x%08x", ret);
if (ret == SCARD_W_REMOVED_CARD)
{
goto retry;
}
else if (ret != SCARD_S_SUCCESS)
{
[err_text setString:#"SCardTransmit failed on CPLC (w/ Le > 0)"];
goto cleanup;
}
// GET RESPONSE
unsigned char get_cplc_command3[] = {0x00, 0xC0, 0x00, 0x00, 0x12};
receive_length = sizeof(receive_buffer);
ret = SCardTransmit(card,
&sendPCI,
get_cplc_command3,
sizeof(get_cplc_command3),
NULL,
receive_buffer,
&receive_length);
LOG(#"SCardTransmit 0x%08x", ret);
if (ret == SCARD_W_REMOVED_CARD)
{
goto retry;
}
else if (ret != SCARD_S_SUCCESS)
{
[err_text setString:#"SCardTransmit failed on CPLC (w/ Le > 0)"];
goto cleanup;
}
NSMutableString* cplc = [[NSMutableString alloc]init];
if (receive_buffer[receive_length-2] == 0x90 &&
receive_buffer[receive_length-1] == 0x00)
{
unsigned char* p = receive_buffer + 3;
NSUInteger size = sizeof(p);
NSMutableString *mutString =[[NSMutableString alloc] init];
for(int i=0;i<=size-1;i++)
{
[mutString appendString:[NSString stringWithFormat:#"%02X",p[i]]];
}
NSString * str = mutString; //#"8510000002030100043DC000C0000000006A9000";
NSMutableString *newString = [[[NSMutableString alloc] init] autorelease];
int i = 0;
while (i < [str length])
{
NSString * hexChar = [str substringWithRange: NSMakeRange(i, 2)];
int value = 0;
sscanf([hexChar cStringUsingEncoding:NSASCIIStringEncoding], "%x", &value);
[newString appendFormat:#"%c", (char)value];
i+=2;
}
}
I am trying to read Smart Card,have got success response after GET RESPONSE command. trying to read receive_buffer data and convert to NSString. But I am getting junk String "=AAj" for newString. Please help me how to read receive_buffer.

Related

Convert NSData to Base-64 wrong

I convert NSString to byte Array. It ok, then I convert NSData to base64 is wrong. if "010203040506" is right but with high number (exam: #"333435363738") is wrong. This is my code. Please help me.
In Android: ISIjJCUm and iOS: MzQ1Njc4.
NSString *command = #"333435363738";
NSMutableData *commandToSend= [[NSMutableData alloc] init];
unsigned long whole_byte;
char byte_chars[3] = {'\0','\0','\0'};
int i;
for (i=0; i < [command length] /2; i++) {
NSLog(#"%d",[command characterAtIndex:i*2]);
NSLog(#"%d",[command characterAtIndex:i*2 + 1]);
byte_chars[0] = [command characterAtIndex:i*2];
byte_chars[1] = [command characterAtIndex:i*2 + 1];
whole_byte = strtol(byte_chars, NULL, 16);
[commandToSend appendBytes:&whole_byte length:1];
}
NSString *base64String;
if ([commandToSend respondsToSelector:#selector(base64EncodedStringWithOptions:)]) {
base64String = [commandToSend base64EncodedStringWithOptions:kNilOptions]; // iOS 7+
} else {
base64String = [commandToSend base64Encoding]; // pre iOS7
}
Your code produces the string MzQ1Njc4 which is the bas64 encoding of the bytes 0x33, 0x34, 0x35, 0x36, 0x37, 0x38. This appears to be what the code is meant to do.
The string ISIjJCUm is the base64 encoding of 0x21, 0x22, 0x23, 0x24, 0x25, 0x26.
Note that 0x21 is 33 decimal. So it looks like you were either meant to interpret the string as decimal on iOS or as hex on Android.

How do I convert an NSString of hex numbers (#"54 2E") to a byte array? [duplicate]

Is there any method in Objective-C that converts a hex string to bytes? For example #"1156FFCD3430AA22" to an unsigned char array {0x11, 0x56, 0xFF, ...}.
Fastest NSString category implementation that I could think of (cocktail of some examples):
- (NSData *)dataFromHexString {
const char *chars = [self UTF8String];
int i = 0, len = self.length;
NSMutableData *data = [NSMutableData dataWithCapacity:len / 2];
char byteChars[3] = {'\0','\0','\0'};
unsigned long wholeByte;
while (i < len) {
byteChars[0] = chars[i++];
byteChars[1] = chars[i++];
wholeByte = strtoul(byteChars, NULL, 16);
[data appendBytes:&wholeByte length:1];
}
return data;
}
It is close to 8 times faster than wookay's solution. NSScanner is quite slow.
#interface NSString (NSStringHexToBytes)
-(NSData*) hexToBytes ;
#end
#implementation NSString (NSStringHexToBytes)
-(NSData*) hexToBytes {
NSMutableData* data = [NSMutableData data];
int idx;
for (idx = 0; idx+2 <= self.length; idx+=2) {
NSRange range = NSMakeRange(idx, 2);
NSString* hexStr = [self substringWithRange:range];
NSScanner* scanner = [NSScanner scannerWithString:hexStr];
unsigned int intValue;
[scanner scanHexInt:&intValue];
[data appendBytes:&intValue length:1];
}
return data;
}
#end
/// example
unsigned char bytes[] = { 0x11, 0x56, 0xFF, 0xCD, 0x34, 0x30, 0xAA, 0x22 };
NSData* expectedData = [NSData dataWithBytes:bytes length:sizeof(bytes)];
NSLog(#"data %#", [#"1156FFCD3430AA22" hexToBytes]);
NSLog(#"expectedData isEqual:%d", [expectedData isEqual:[#"1156FFCD3430AA22" hexToBytes]]);
The scanHexInt: and similar methods of NSScanner might be helpful in doing what you want, but you'd probably need to break the string up into smaller chunks first, in which case doing the translation manually might be simpler than using NSScanner.
Not in the way you are doing it. You'll need to write your own method to take every two characters, interpret them as an int, and store them in an array.
Modified approach,
/* Converts a hex string to bytes.
Precondition:
. The hex string can be separated by space or not.
. the string length without space or 0x, must be even. 2 symbols for one byte/char
. sample input: 23 3A F1 OR 233AF1, 0x23 0X231f 2B
*/
+ (NSData *) dataFromHexString:(NSString*)hexString
{
NSString * cleanString = [Util cleanNonHexCharsFromHexString:hexString];
if (cleanString == nil) {
return nil;
}
NSMutableData *result = [[NSMutableData alloc] init];
int i = 0;
for (i = 0; i+2 <= cleanString.length; i+=2) {
NSRange range = NSMakeRange(i, 2);
NSString* hexStr = [cleanString substringWithRange:range];
NSScanner* scanner = [NSScanner scannerWithString:hexStr];
unsigned int intValue;
[scanner scanHexInt:&intValue];
unsigned char uc = (unsigned char) intValue;
[result appendBytes:&uc length:1];
}
NSData * data = [NSData dataWithData:result];
[result release];
return data;
}
/* Clean a hex string by removing spaces and 0x chars.
. The hex string can be separated by space or not.
. sample input: 23 3A F1; 233AF1; 0x23 0x3A 0xf1
*/
+ (NSString *) cleanNonHexCharsFromHexString:(NSString *)input
{
if (input == nil) {
return nil;
}
NSString * output = [input stringByReplacingOccurrencesOfString:#"0x" withString:#""
options:NSCaseInsensitiveSearch range:NSMakeRange(0, input.length)];
NSString * hexChars = #"0123456789abcdefABCDEF";
NSCharacterSet *hexc = [NSCharacterSet characterSetWithCharactersInString:hexChars];
NSCharacterSet *invalidHexc = [hexc invertedSet];
NSString * allHex = [[output componentsSeparatedByCharactersInSet:invalidHexc] componentsJoinedByString:#""];
return allHex;
}
First attempt in Swift 2.2:
func hexStringToBytes(hexString: String) -> NSData? {
guard let chars = hexString.cStringUsingEncoding(NSUTF8StringEncoding) else { return nil}
var i = 0
let length = hexString.characters.count
let data = NSMutableData(capacity: length/2)
var byteChars: [CChar] = [0, 0, 0]
var wholeByte: CUnsignedLong = 0
while i < length {
byteChars[0] = chars[i]
i+=1
byteChars[1] = chars[i]
i+=1
wholeByte = strtoul(byteChars, nil, 16)
data?.appendBytes(&wholeByte, length: 1)
}
return data
}
Or, as an extension on String:
extension String {
func dataFromHexString() -> NSData? {
guard let chars = cStringUsingEncoding(NSUTF8StringEncoding) else { return nil}
var i = 0
let length = characters.count
let data = NSMutableData(capacity: length/2)
var byteChars: [CChar] = [0, 0, 0]
var wholeByte: CUnsignedLong = 0
while i < length {
byteChars[0] = chars[i]
i+=1
byteChars[1] = chars[i]
i+=1
wholeByte = strtoul(byteChars, nil, 16)
data?.appendBytes(&wholeByte, length: 1)
}
return data
}
}
This is a continuous work-in-progress, but appears to work well so far.
Further optimizations and a more in-depth discussion can be found on Code Review.
Several solution is returned wrong value if the string like this
"DBA"
The correct data for "DBA" string is "\x0D\xBA" (int value : 3514)
if you got a data is not like this "\x0D\xBA" it mean you got a wrong byte because the value will be different, for example you got data like this "\xDB\x0A" the int value is 56074
Here is rewrite the solution:
+ (NSData *)dataFromHexString:(NSString *) string {
if([string length] % 2 == 1){
string = [#"0"stringByAppendingString:string];
}
const char *chars = [string UTF8String];
int i = 0, len = (int)[string length];
NSMutableData *data = [NSMutableData dataWithCapacity:len / 2];
char byteChars[3] = {'\0','\0','\0'};
unsigned long wholeByte;
while (i < len) {
byteChars[0] = chars[i++];
byteChars[1] = chars[i++];
wholeByte = strtoul(byteChars, NULL, 16);
[data appendBytes:&wholeByte length:1];
}
return data;
}

How to put a Hex string to byte array in Objective C [duplicate]

Is there any method in Objective-C that converts a hex string to bytes? For example #"1156FFCD3430AA22" to an unsigned char array {0x11, 0x56, 0xFF, ...}.
Fastest NSString category implementation that I could think of (cocktail of some examples):
- (NSData *)dataFromHexString {
const char *chars = [self UTF8String];
int i = 0, len = self.length;
NSMutableData *data = [NSMutableData dataWithCapacity:len / 2];
char byteChars[3] = {'\0','\0','\0'};
unsigned long wholeByte;
while (i < len) {
byteChars[0] = chars[i++];
byteChars[1] = chars[i++];
wholeByte = strtoul(byteChars, NULL, 16);
[data appendBytes:&wholeByte length:1];
}
return data;
}
It is close to 8 times faster than wookay's solution. NSScanner is quite slow.
#interface NSString (NSStringHexToBytes)
-(NSData*) hexToBytes ;
#end
#implementation NSString (NSStringHexToBytes)
-(NSData*) hexToBytes {
NSMutableData* data = [NSMutableData data];
int idx;
for (idx = 0; idx+2 <= self.length; idx+=2) {
NSRange range = NSMakeRange(idx, 2);
NSString* hexStr = [self substringWithRange:range];
NSScanner* scanner = [NSScanner scannerWithString:hexStr];
unsigned int intValue;
[scanner scanHexInt:&intValue];
[data appendBytes:&intValue length:1];
}
return data;
}
#end
/// example
unsigned char bytes[] = { 0x11, 0x56, 0xFF, 0xCD, 0x34, 0x30, 0xAA, 0x22 };
NSData* expectedData = [NSData dataWithBytes:bytes length:sizeof(bytes)];
NSLog(#"data %#", [#"1156FFCD3430AA22" hexToBytes]);
NSLog(#"expectedData isEqual:%d", [expectedData isEqual:[#"1156FFCD3430AA22" hexToBytes]]);
The scanHexInt: and similar methods of NSScanner might be helpful in doing what you want, but you'd probably need to break the string up into smaller chunks first, in which case doing the translation manually might be simpler than using NSScanner.
Not in the way you are doing it. You'll need to write your own method to take every two characters, interpret them as an int, and store them in an array.
Modified approach,
/* Converts a hex string to bytes.
Precondition:
. The hex string can be separated by space or not.
. the string length without space or 0x, must be even. 2 symbols for one byte/char
. sample input: 23 3A F1 OR 233AF1, 0x23 0X231f 2B
*/
+ (NSData *) dataFromHexString:(NSString*)hexString
{
NSString * cleanString = [Util cleanNonHexCharsFromHexString:hexString];
if (cleanString == nil) {
return nil;
}
NSMutableData *result = [[NSMutableData alloc] init];
int i = 0;
for (i = 0; i+2 <= cleanString.length; i+=2) {
NSRange range = NSMakeRange(i, 2);
NSString* hexStr = [cleanString substringWithRange:range];
NSScanner* scanner = [NSScanner scannerWithString:hexStr];
unsigned int intValue;
[scanner scanHexInt:&intValue];
unsigned char uc = (unsigned char) intValue;
[result appendBytes:&uc length:1];
}
NSData * data = [NSData dataWithData:result];
[result release];
return data;
}
/* Clean a hex string by removing spaces and 0x chars.
. The hex string can be separated by space or not.
. sample input: 23 3A F1; 233AF1; 0x23 0x3A 0xf1
*/
+ (NSString *) cleanNonHexCharsFromHexString:(NSString *)input
{
if (input == nil) {
return nil;
}
NSString * output = [input stringByReplacingOccurrencesOfString:#"0x" withString:#""
options:NSCaseInsensitiveSearch range:NSMakeRange(0, input.length)];
NSString * hexChars = #"0123456789abcdefABCDEF";
NSCharacterSet *hexc = [NSCharacterSet characterSetWithCharactersInString:hexChars];
NSCharacterSet *invalidHexc = [hexc invertedSet];
NSString * allHex = [[output componentsSeparatedByCharactersInSet:invalidHexc] componentsJoinedByString:#""];
return allHex;
}
First attempt in Swift 2.2:
func hexStringToBytes(hexString: String) -> NSData? {
guard let chars = hexString.cStringUsingEncoding(NSUTF8StringEncoding) else { return nil}
var i = 0
let length = hexString.characters.count
let data = NSMutableData(capacity: length/2)
var byteChars: [CChar] = [0, 0, 0]
var wholeByte: CUnsignedLong = 0
while i < length {
byteChars[0] = chars[i]
i+=1
byteChars[1] = chars[i]
i+=1
wholeByte = strtoul(byteChars, nil, 16)
data?.appendBytes(&wholeByte, length: 1)
}
return data
}
Or, as an extension on String:
extension String {
func dataFromHexString() -> NSData? {
guard let chars = cStringUsingEncoding(NSUTF8StringEncoding) else { return nil}
var i = 0
let length = characters.count
let data = NSMutableData(capacity: length/2)
var byteChars: [CChar] = [0, 0, 0]
var wholeByte: CUnsignedLong = 0
while i < length {
byteChars[0] = chars[i]
i+=1
byteChars[1] = chars[i]
i+=1
wholeByte = strtoul(byteChars, nil, 16)
data?.appendBytes(&wholeByte, length: 1)
}
return data
}
}
This is a continuous work-in-progress, but appears to work well so far.
Further optimizations and a more in-depth discussion can be found on Code Review.
Several solution is returned wrong value if the string like this
"DBA"
The correct data for "DBA" string is "\x0D\xBA" (int value : 3514)
if you got a data is not like this "\x0D\xBA" it mean you got a wrong byte because the value will be different, for example you got data like this "\xDB\x0A" the int value is 56074
Here is rewrite the solution:
+ (NSData *)dataFromHexString:(NSString *) string {
if([string length] % 2 == 1){
string = [#"0"stringByAppendingString:string];
}
const char *chars = [string UTF8String];
int i = 0, len = (int)[string length];
NSMutableData *data = [NSMutableData dataWithCapacity:len / 2];
char byteChars[3] = {'\0','\0','\0'};
unsigned long wholeByte;
while (i < len) {
byteChars[0] = chars[i++];
byteChars[1] = chars[i++];
wholeByte = strtoul(byteChars, NULL, 16);
[data appendBytes:&wholeByte length:1];
}
return data;
}

Converting NSData to SecKeyRef

i have a public key which i gathered from a remote server and i want to perform RSA encryption with that public key. But the problem is i get the public key data as byte array in buffer. I can convert it to NSData but i can not convert to SecKeyRef so i can keep going with encryption. My encryption code is like:
+(NSString *)encryptRSA:(NSString *)plainTextString withKey:(SecKeyRef)publicKey {
size_t cipherBufferSize = SecKeyGetBlockSize(publicKey);
uint8_t *cipherBuffer = malloc(cipherBufferSize);
uint8_t *nonce = (uint8_t *)[plainTextString UTF8String];
SecKeyEncrypt(publicKey,
kSecPaddingOAEP,
nonce,
strlen( (char*)nonce ),
&cipherBuffer[0],
&cipherBufferSize);
NSData *encryptedData = [NSData dataWithBytes:cipherBuffer length:cipherBufferSize];
return [encryptedData base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
}
As you can see i need SecKeyRef object type to complete my encryption. But my RSA public key is in NSData variable. So how can i convert NSData to SecKeyRef object type. Thanks in advance.
Use this function to save your public key. Pass your RAS public key and any name for peername.
- (void)addPeerPublicKey:(NSString *)peerName keyBits:(NSData *)publicKeyData {
OSStatus sanityCheck = noErr;
CFTypeRef persistPeer = NULL;
[self removePeerPublicKey:peerName];
NSData * peerTag = [[NSData alloc] initWithBytes:(const void *)[peerName UTF8String] length:[peerName length]];
NSMutableDictionary * peerPublicKeyAttr = [[NSMutableDictionary alloc] init];
[peerPublicKeyAttr setObject:(id)kSecClassKey forKey:(id)kSecClass];
[peerPublicKeyAttr setObject:(id)kSecAttrKeyTypeRSA forKey:(id)kSecAttrKeyType];
[peerPublicKeyAttr setObject:peerTag forKey:(id)kSecAttrApplicationTag];
[peerPublicKeyAttr setObject:publicKeyData forKey:(id)kSecValueData];
[peerPublicKeyAttr setObject:[NSNumber numberWithBool:YES] forKey:(id)kSecReturnData];
sanityCheck = SecItemAdd((CFDictionaryRef) peerPublicKeyAttr, (CFTypeRef *)&persistPeer);
if(sanityCheck == errSecDuplicateItem){
TRC_DBG(#"Problem adding the peer public key to the keychain, OSStatus == %ld.", sanityCheck );
}
TRC_DBG(#"SecItemAdd OSStATUS = %ld", sanityCheck);
// TRC_DBG(#"PersistPeer privatekey data after import into keychain %#", persistPeer);
persistPeer = NULL;
[peerPublicKeyAttr removeObjectForKey:(id)kSecValueData];
sanityCheck = SecItemCopyMatching((CFDictionaryRef) peerPublicKeyAttr, (CFTypeRef*)&persistPeer);
TRC_DBG(#"SecItemCopying OSStATUS = %ld", sanityCheck);
// TRC_DBG(#"SecItem copy matching returned this public key data %#", persistPeer);
// The nice thing about persistent references is that you can write their value out to disk and
// then use them later. I don't do that here but it certainly can make sense for other situations
// where you don't want to have to keep building up dictionaries of attributes to get a reference.
//
// Also take a look at SecKeyWrapper's methods (CFTypeRef)getPersistentKeyRefWithKeyRef:(SecKeyRef)key
// & (SecKeyRef)getKeyRefWithPersistentKeyRef:(CFTypeRef)persistentRef.
[peerTag release];
[peerPublicKeyAttr release];
if (persistPeer) CFRelease(persistPeer);
}
This is the function to retrieve the public key ref. Pass the same name which one is used for save.
-(SecKeyRef)getPublicKeyReference:(NSString*)peerName{
OSStatus sanityCheck = noErr;
SecKeyRef pubKeyRefData = NULL;
NSData * peerTag = [[NSData alloc] initWithBytes:(const void *)[peerName UTF8String] length:[peerName length]];
NSMutableDictionary * peerPublicKeyAttr = [[NSMutableDictionary alloc] init];
[peerPublicKeyAttr setObject:(id)kSecClassKey forKey:(id)kSecClass];
[peerPublicKeyAttr setObject:(id)kSecAttrKeyTypeRSA forKey:(id)kSecAttrKeyType];
[peerPublicKeyAttr setObject:peerTag forKey:(id)kSecAttrApplicationTag];
[peerPublicKeyAttr setObject:[NSNumber numberWithBool:YES] forKey: (id)kSecReturnRef];
sanityCheck = SecItemCopyMatching((CFDictionaryRef) peerPublicKeyAttr, (CFTypeRef*)&pubKeyRefData);
[peerTag release];
[peerPublicKeyAttr release];
TRC_DBG(#"SecItemCopying OSStATUS = %ld", sanityCheck);
if(pubKeyRefData){
TRC_DBG(#"SecItem copy matching returned this publickeyref %#", pubKeyRefData);
return pubKeyRefData;
}else{
TRC_DBG(#"pubKeyRef is NULL");
return nil;
}
}
Pass your public key data to this function before addPeerPublicKey
- (NSData *)stripPublicKeyHeader:(NSData *)d_key
{
// Skip ASN.1 public key header
if (d_key == nil) return(nil);
unsigned int len = [d_key length];
if (!len) return(nil);
unsigned char *c_key = (unsigned char *)[d_key bytes];
unsigned int idx = 0;
if (c_key[idx++] != 0x30) return(nil);
if (c_key[idx] > 0x80) idx += c_key[idx] - 0x80 + 1;
else idx++;
// PKCS #1 rsaEncryption szOID_RSA_RSA
static unsigned char seqiod[] =
{ 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
0x01, 0x05, 0x00 };
if (memcmp(&c_key[idx], seqiod, 15)) return(nil);
idx += 15;
if (c_key[idx++] != 0x03) return(nil);
if (c_key[idx] > 0x80) idx += c_key[idx] - 0x80 + 1;
else idx++;
if (c_key[idx++] != '\0') return(nil);
// Now make a new NSData from this buffer
return([NSData dataWithBytes:&c_key[idx] length:len - idx]);
}
Hope It will work....
-(NSData*)convertIOSKeyToASNFormat:(NSData*)iosKey{
static const unsigned char _encodedRSAEncryptionOID[15] = {
/* Sequence of length 0xd made up of OID followed by NULL */
0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00
};
// OK - that gives us the "BITSTRING component of a full DER
// encoded RSA public key - we now need to build the rest
unsigned char builder[15];
NSMutableData * encKey = [[[NSMutableData alloc] init] autorelease];
int bitstringEncLength;
// When we get to the bitstring - how will we encode it?
if ([iosKey length ] + 1 < 128 )
bitstringEncLength = 1 ;
else
bitstringEncLength = (([iosKey length ] +1 ) / 256 ) + 2 ;
// Overall we have a sequence of a certain length
builder[0] = 0x30; // ASN.1 encoding representing a SEQUENCE
// Build up overall size made up of -
size_t i = sizeof(_encodedRSAEncryptionOID) + 2 + bitstringEncLength +
[iosKey length];
size_t j = [self encodeLen:&builder[1] length:i];
[encKey appendBytes:builder length:j +1];
// First part of the sequence is the OID
[encKey appendBytes:_encodedRSAEncryptionOID
length:sizeof(_encodedRSAEncryptionOID)];
// Now add the bitstring
builder[0] = 0x03;
j = [self encodeLen:&builder[1] length:[iosKey length] + 1];
builder[j+1] = 0x00;
[encKey appendBytes:builder length:j + 2];
// Now the actual key
[encKey appendData:iosKey];
return encKey;
}

Remove NSString from memory

I have to remove an NSString (containing some confidential data) from memory but not only by setting it to nil, but by nullifying it's bytes. What I've tried so far is:
NSString *str = #"test";
NSLog(#"original string:%#", str);
CFStringRef ref = (__bridge CFStringRef)str;
const char * strPtr = CFStringGetCStringPtr(ref, kCFStringEncodingUTF8);
memset(strPtr, 0, [str lengthOfBytesUsingEncoding:NSUTF8StringEncoding]);
NSLog(#"cleared string:%#", str);
but the function CFStringGetCStringPtr is returning NULL so it crashes at the line with the memset. Apple says here that in some cases it is normal for that function to return NULL, but then I don't know how to solve this.
Thanks in advance
Don't store confident data as strings. You can't remove them from memory easily.
If possible, use NSMutableData to store confident data, instead.
Try This:
NSMutableString *str = [NSMutableString stringWithString:#"test"];
NSLog(#"original string:%#", str);
CFStringRef ref = ( CFStringRef)str;
CFIndex stringLength = CFStringGetLength(ref), usedBytes = 0L;
const char * strPtr = NULL;
strPtr = CFStringGetCStringPtr(ref, kCFStringEncodingUTF8);
char *freeUTF8StringPtr = NULL;
for(CFIndex idx = 0L; (strPtr != NULL) && (strPtr[idx] != 0); idx++)
{
if(strPtr[idx] >= 128) { strPtr = NULL; }
}
if((strPtr == NULL) && ((freeUTF8StringPtr = malloc(stringLength + 1L)) != NULL))
{
CFStringGetBytes(ref, CFRangeMake(0L, stringLength), kCFStringEncodingUTF8, '?', false, (UInt8*)freeUTF8StringPtr, stringLength, &usedBytes);
freeUTF8StringPtr[usedBytes] = 0;
strPtr = (const char *)freeUTF8StringPtr;
}
NSUInteger memorySize=[str lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
NSLog(#"cleared string:%#", str);
I have tried something like this below:-
NSMutableString *str = #"test";
NSLog(#"original string:%#", str);
CFStringRef ref = (__bridge CFStringRef)str;//kCFStringEncodingUTF16
const char * strPtr = CFStringGetCStringPtr(ref, kCFStringEncodingUTF16);
NSUInteger memorySize=[str lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
NSLog(#"cleared string:%d", memorySize);
Output := 4

Resources