最近程序里面要调用底层C库。C接口里面有个入参是要传入一个字节数组进去,底层库会把这个字节数组通过网络传输给其他人。但是在应用上层,传入的是一个字符串。为了接收方能正常将收到的字节数组解析出里面的内容,传入的字节数组必须是将应用上层传过来的字符串转换为其对应的GBK编码后的字节数组。
ios 上层传入字符串,是NSString类型的。NSString转UTF字节码有现成的方法可用。转其它编码的字节码,有个- (NSData *)dataUsingEncoding:(NSStringEncoding)encoding的方法。
看了下NSStringEncoding是NSUInteger类型的,通常是unsigned int32,在64位上就是unsigned 64了。本来在NSString的参考文档里面,对字符集有枚举类型的定义。
但是在里面没发现GBK编码的,后面在NSString参考文档中找到了可以列举操作系统支持的自负编码的方法:+ (const NSStringEncoding *)availableStringEncodings 和可以打印对应编码名字的方法:+ (NSString *)localizedNameOfStringEncoding:(NSStringEncoding)encoding 。
这样,我就先把操作系统支持的所有字符编码枚举了并打印了出来。
1 const NSStringEncoding *encoding = [NSString availableStringEncodings]; 2 3 while((*encoding) != 0) 4 { 5 NSLog(@"%@ ====>%lu",[NSString localizedNameOfStringEncoding:*encoding],*encoding); 6 encoding ++; 7 }
结果找到如下:
2014-05-11 21:48:12.277 CharsetEncoderForMac[1224:303] Chinese (GBK) ====>2147485233
2014-05-11 21:48:12.278 CharsetEncoderForMac[1224:303] Chinese (GB 18030) ====>2147485234
之后,为了验证,专门写了java的和ios的测试代码来做比对:
1 NSString *name = @"雷佩"; 2 NSData *data = [name dataUsingEncoding:2147485233]; 3 4 NSUInteger len = [data length]; 5 char dataPointer[len] ; 6 [data getBytes:dataPointer]; 7 for (int i =0; i<len; i++) { 8 NSLog(@"%d",dataPointer[i]); 9 }
public String encode(String inputStr) { StringBuilder outPutStrBuilder = new StringBuilder(); if (null != inputStr && inputStr.length() > 0) { byte[] bytesArray = null; bytesArray = inputStr.getBytes(this.charset); int len = bytesArray.length; for (int i = 0; i < len; i++) { outPutStrBuilder.append(String.format("0x%x ", bytesArray[i])); } int outStrLen = outPutStrBuilder.length(); if (outStrLen > 0) { return outPutStrBuilder.substring(0, outStrLen-2); } } return outPutStrBuilder.toString(); }
最终结果一致。
20140720补充:
上面的objc代码实际上是在mac 命令行程序中跑出来的。后面在模拟器上做了验证后发现,手机上不支持GBK,但支持GB18030和GB2312。