Objective c 将NSData字节转换为NSString

Objective c 将NSData字节转换为NSString,objective-c,c,cocoa,encryption,Objective C,C,Cocoa,Encryption,我正在尝试在objective-c(Mac OS)中创建一个16字节和更高版本的32字节初始化向量。我编写了一些关于如何创建随机字节的代码,并将其修改为16字节,但在这方面我有一些困难。NSData转储十六进制,但NSString转储给出nil,cstring NSLog给出错误的字符数(此处转储中没有复制相同的字符) 这是我的终端输出: 2012-01-07 14:29:07.705 Test3Test[4633:80f] iv hex <48ea262d efd8f5f5 f80211

我正在尝试在objective-c(Mac OS)中创建一个16字节和更高版本的32字节初始化向量。我编写了一些关于如何创建随机字节的代码,并将其修改为16字节,但在这方面我有一些困难。NSData转储十六进制,但NSString转储给出nil,cstring NSLog给出错误的字符数(此处转储中没有复制相同的字符)

这是我的终端输出:

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
(我在上面留下了一些我尝试过但也不起作用的注释代码)

下面是我的随机数生成器,取自堆栈溢出示例:

@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
@实现测试类
-(NSData*)创建随机NSData
{
int-twentyMb=16;
NSMutableData*数据=[NSMutableData数据,容量:twentyMb];
用于(无符号整数i=0;i
我真的不知道这里会有什么问题。如果我把数据作为字节,它应该转换成字符串还是不一定?我已经查看了这里有关stackoverflow的相关示例,但没有一个在这种情况下有效

谢谢,
Elijah

当使用UTF8编码将NSData转换为NSString时,您不一定会得到相同的字节数,因为并非所有二进制值都是有效的字符编码。我要说的是,使用字符串来处理二进制数据是一种解决问题的方法


这个字符串有什么用?NSData正是存储二进制数据的数据类型。

任意字节序列可能不是合法的UTF8编码。正如@Joachim Isaksson所指出的,很少有理由以这种方式转换为字符串。如果需要将随机数据存储为字符串,则应使用Base64之类的编码方案,将
NSData
序列化为plist,或类似方法。您也不能简单地使用cstring,因为
NULL
在随机字节序列中是合法的,但在cstring中是不合法的

您不需要在Mac或iOS上构建自己的随机字节创建者。有一个内置的名为
SecRandomCopyBytes()
。例如(来自):


字符串的用途是将值存储在数据库中。另外,您是否知道AES密文是否始终是有效的UTF8字符串?AES密文不保证是有效的UTF8字符串。好的,因此我应该对密码和IV进行base64编码。但是,到目前为止,我始终能够将密文打印为nsstring,然而,我从来没有能够转换这些随机字节-但我会留在安全的一面,b64编码它。我过去无法使用int result=SecRandomCopyBytes(kSecRandomDefault,length,data.mutableBytes);编译要求我提供kSecRandomDefault,我感觉这个函数只是iOS(我的通用加密版本有不同的头文件),如果需要以7位安全的方式(如电子邮件)存储密码,您应该只对密码和IV进行base64编码。如果您可以将它们写入一个文件,那么就没有理由对它们进行编码。写下来就行了。SecRandomCopyBytes()是在10.7中添加的(我之前没有注意到)。如果你想支持它,源代码在opensource.apple.com上,我建议你还是自己创建吧。
@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
+ (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;
}