ASCII到NSData

Jim*_*ann 0 cocoa extended-ascii nsdata

这是我的MD5问题的另一个问题.我知道问题是ASCII字符©(0xa9,169).要么是我将字符插入字符串的方式,要么是高字节和低字节问题.

如果我

 NSString *source = [NSString stringWithFormat:@"%c", 0xa9];

    NSData *data = [source dataUsingEncoding:NSASCIIStringEncoding];

    NSLog(@"\n\n ############### source %@ \ndata desc %@", source, [data description]);

CC_MD5([data bytes], [data length], result);

     return [NSString stringWithFormat:
   @"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
   result[0], result[1], result[2], result[3], 
   result[4], result[5], result[6], result[7],
   result[8], result[9], result[10], result[11],
   result[12], result[13], result[14], result[15]
   ];
Run Code Online (Sandbox Code Playgroud)

结果:

######### source©

[数据描述] =(null)
md5:d41d8cd98f00b204e9800998ecf8427e

值:int 169 char©

当我将编码更改为

NSData *data = [NSData dataWithBytes:[source UTF8String] length:[source length]];
Run Code Online (Sandbox Code Playgroud)

结果是

######### source©

[数据描述] ="<"c2>
md5:6465dad1d31752be3f3283e8f70feef7

当我将编码更改为

NSData *data = [NSData dataWithBytes:[source UTF8String] length:[source lengthOfBytesUsingEncoding:NSUTF8StringEncoding]];
Run Code Online (Sandbox Code Playgroud)

结果是############### source©len 2 [数据描述] ="<"c2a9>
md5:a541ecda3d4c67f1151cad5075633423

当我在Java中运行相同的函数时,我得到了

">>>>> msg ##\251\251
md5 a252c2c85a9e7756d5ba5da9949d57ed

问题是在objC中获取相同字节的最佳方法是什么?

Pet*_*sey 6

"ASCII到NSData"毫无意义,因为ASCII是一种编码; 如果你有编码字符,那么你有数据.

编码是将理想的Unicode字符(代码点)转换为一个或多个字节的单元(代码单元),可能是UTF-16的代理对等序列.

NSString或多或少是理想的Unicode对象.它包含字符的字符串,Unicode中,无论任何编码的*.

ASCII是一种编码.UTF-8也是一种编码.当你询问字符串时UTF8String,你要求它将其字符编码为UTF-8.

NSData *data = [NSData dataWithBytes:[source UTF8String] length:[source length]];
Run Code Online (Sandbox Code Playgroud)

结果是

 ######### source ©
 [data description] = "<"c2>
Run Code Online (Sandbox Code Playgroud)

那是因为你通过了错误的长度.字符串的长度(以字符为单位)与某些编码中的代码单元数(在本例中为字节数)不同.

正确的长度是strlen([source UTF8String]),但是对您来说更容易,并且在运行时更快dataUsingEncoding:地要求字符串为您创建NSData对象.

当我将编码更改为

NSData *data = [NSData dataWithBytes:[source UTF8String] length:[source lengthOfBytesUsingEncoding:NSUTF8StringEncoding]];
Run Code Online (Sandbox Code Playgroud)

您没有更改编码.你仍然将它编码为UTF-8.

使用dataUsingEncoding:.

问题是在objC中获取相同字节的最佳方法是什么?

使用相同的编码.

没有"扩展ASCII"这样的东西.有几种不同的编码基于(或至少兼容)ASCII,包括ISO 8859-1,ISO 8859-9,MacRoman,Windows代码页1252和UTF-8.你需要决定你的意思,并告诉字符串用它来编码它的字符.

更好的是,继续使用UTF-8 - 它几乎总是大多数ASCII文本的正确选择 - 而是改变你的Java代码.

NSData *data = [source dataUsingEncoding:NSASCIIStringEncoding];
Run Code Online (Sandbox Code Playgroud)

结果:

[data description] = (null)
Run Code Online (Sandbox Code Playgroud)

True ASCII只能编码128个可能的字符.Unicode包括所有未更改的ASCII,因此Unicode中的前128个代码点是ASCII可以编码的.除此之外,ASCII无法编码.

我见过的NSASCIIStringEncoding表现与NSISOLatin1StringEncoding以前相同; 听起来他们可能已经将它改为纯ASCII编码,如果是这样的话,这是件好事.ASCII中没有版权符号.你在这里看到的是正确的结果.


*这不是真的; 字符显示为UTF-16,因此基本多语言平面之外的任何字符都作为代理对显示,而不是整个字符,因为它们将是真正理想的字符串对象.这是一种权衡.在Swift中,内置的String类型是一个完美的理想Unicode对象; 字符是字符,在编码之前从不分割.但是在使用NSString时(无论是在Swift中还是在Objective-C中),就您而言,您应该将其视为理想的字符串.