cocoa - ASCII 到 NSData

标签 cocoa nsdata extended-ascii

这是对我的 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]
   ];

结果:

#########来源©

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

值:int 169 char ©

当我将编码更改为

NSData *data = [NSData dataWithBytes:[source UTF8String] length:[source length]];

结果是

#########来源©

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

当我将编码更改为

NSData *data = [NSData dataWithBytes:[source UTF8String] length:[source lengthOfBytesUsingEncoding:NSUTF8StringEncoding]];

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

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

">>>>> 消息##\251\251
md5 a252c2c85a9e7756d5ba5da9949d57ed

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

最佳答案

“ASCII to NSData”没有任何意义,因为 ASCII 是一种编码;如果你有编码字符,那么你就有数据。

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

NSString 或多或少是一个理想的 Unicode 对象。它包含字符串的字符,采用 Unicode,与任何编码无关*。

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

NSData *data = [NSData dataWithBytes:[source UTF8String] length:[source length]];

The result is

 ######### source ©
 [data description] = "<"c2>

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

正确的长度是 strlen([source UTF8String]),但使用 dataUsingEncoding: 要求字符串创建为您提供 NSData 对象。

When I change the encoding to

NSData *data = [NSData dataWithBytes:[source UTF8String] length:[source lengthOfBytesUsingEncoding:NSUTF8StringEncoding]];

您没有更改编码。您仍然将其编码为 UTF-8。

使用dataUsingEncoding:

The question is what is the best way to get the same byte in objC as I get in Java?

使用相同的编码。

不存在“扩展 ASCII”这样的东西。有多种基于(或至少兼容)ASCII 的不同编码,包括 ISO 8859-1、ISO 8859-9、MacRoman、Windows 代码页 1252 和 UTF-8。您需要决定您指的是哪一个,并告诉字符串用它对其字符进行编码。

更好的是,继续使用 UTF-8(对于大多数 ASCII 文本来说它几乎总是正确的选择)并更改您的 Java 代码。

NSData *data = [source dataUsingEncoding:NSASCIIStringEncoding];

Result:

[data description] = (null)

真正的 ASCII 只能编码 128 个可能的字符。 Unicode 包含所有未更改的 ASCII,因此 Unicode 中的前 128 个代码点是 ASCII 可以编码的内容。其他任何东西,ASCII 都无法编码​​。

我之前见过 NSASCIIStringEncoding 的行为与 NSISOLatin1StringEncoding 相同;听起来他们可能已经将其更改为纯 ASCII 编码,如果是这样的话,那是一件好事。 ASCII 中没有版权符号。您在这里看到的是正确的结果。

<小时/>

*这并不完全正确;字符被公开为 UTF-16,因此基本多语言平面之外的任何字符都被公开为代理对,而不是像在真正理想的字符串对象中那样的整个字符。这是一个权衡。在 Swift 中,内置的 String 类型是一个完美理想的 Unicode 对象;字符就是字符,在编码之前不会被分割。但是当使用 NSString 时(无论是在 Swift 还是 Objective-C),就你而言,你应该将它视为理想的字符串。

关于cocoa - ASCII 到 NSData,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4269094/

相关文章:

ios - NSData getBytes 随机返回垃圾

linux - 如何使用 grep 命令计算扩展 ASCII 字符

iphone - 使用 segue 将 NSMutableArray 字典数据传递到另一个 View

iPhone 工具栏由多个 View 共享

xcode - 如何更改 NSTextView 中的字体颜色?

ruby - 在 Ruby 中将字符串从 UTF-8 转码为 ASCII-8BIT?

c++ - Code::Blocks C++ 中的扩展 Ascii 字符

ios - 在 Swift 中从 Objective-C 访问 extern NSString

iphone - 将 nsdictionary 转换为 nsdata

iPhone - 转换为 NSData?