简体   繁体   中英

Converting NSData bytes to NSString

I am trying to create a 16 byte and later 32 byte initialization vector in objective-c (Mac OS). I took some code on how to create random bytes and modified it to 16 bytes, but I have some difficulty with this. The NSData dumps the hex, but an NSString dump gives nil, and a cstring NSLog gives the wrong number of characters (not reproduced the same in the dump here).

Here is my terminal output:

2012-01-07 14:29:07.705 Test3Test[4633:80f] iv hex <48ea262d efd8f5f5 f8021126 fd74c9fd>
2012-01-07 14:29:07.710 Test3Test[4633:80f] IV string: (null)
2012-01-07 14:29:07.711 Test3Test[4633:80f] IV char string t^Q¶�^��^A

Here is the main program:

int main (int argc, const char * argv[])
{
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
    //NSString *iv_string = [NSString stringWithCString:iv encoding:NSUTF8StringEncoding];
    testclass *obj = [testclass alloc];
    NSData *iv_data = [obj createRandomNSData];
    //[iv_string dataUsingEncoding:NSUTF8StringEncoding];
    NSLog(@"iv hex %@",iv_data);

    //NSString *iv_string = [[NSString alloc] initWithBytes:[iv_data bytes] length:16 encoding:NSUTF8StringE$
    NSString *iv_string = [[NSString alloc] initWithData:iv_data encoding:NSUTF8StringEncoding];
    NSLog(@"IV string: %@",iv_string);
    NSLog(@"IV char string %.*s",[iv_data bytes]);

    return 0;
]

(I left in the above some commented code that I tried and did not work also).

Below is my random number generater, taken from a stack overflow example:

@implementation testclass
-(NSData*)createRandomNSData
{
    int twentyMb           = 16;
    NSMutableData* theData = [NSMutableData dataWithCapacity:twentyMb];
    for( unsigned int i = 0 ; i < twentyMb/4 ; ++i )
    {
            u_int32_t randomBits = arc4random();
            [theData appendBytes:(void*)&randomBits length:4];
    }
    NSData *data = [NSData dataWithData:theData];
    [theData dealloc];
    return data;
}
@end

I am really quite clueless as to what could be the problem here. If I have data as bytes, it should convert to a string or not necessarily? I have looked over the relevant examples here on stackoverflow, but none of them have worked in this situation.

Thanks, Elijah

An arbitrary byte sequence may not be legal UTF8 encoding. As @Joachim Isaksson notes, there is seldom reason to convert to strings this way. If you need to store random data as a string, you should use an encoding scheme like Base64, serialize the NSData to a plist, or similar approach. You cannot simply use a cstring either, since NULL is legal inside of a random byte sequence, but is not legal inside of a cstring.

You do not need to build your own random byte creator on Mac or iOS. There's one built-in called SecRandomCopyBytes() . For example (from Properly encrypting with AES with CommonCrypto ):

+ (NSData *)randomDataOfLength:(size_t)length {
  NSMutableData *data = [NSMutableData dataWithLength:length];

  int result = SecRandomCopyBytes(kSecRandomDefault, 
                                  length,
                                  data.mutableBytes);
  NSAssert(result == 0, @"Unable to generate random bytes: %d",
           errno);

  return data;
}

When converting NSData to NSString using an UTF8 encoding, you won't necessarily end up with the same number of bytes since not all binary values are valid encodings of characters. I'd say using a string for binary data is a recipe for problems.

What is the use of the string? NSData is exactly the datatype you want for storing binary data to begin with.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM