最近程序里面要調用底層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。