汉字使用 cString 转换的乱码问题

2022-06-14 11:14:17 +08:00
 pheyer

假如给定一串乱码Âà†Èô§Â§±Ë¥•,已知它的实际内容为 4 个汉字,你能这些乱码恢复出真实的汉字出来吗?

我使用几个提供乱码文字恢复服务的网站,都没能把它恢复出来。

其实这段乱码是这样产生的:见下面的代码,对于指定汉字字符串,先转换为 c 字符串,再使用 initWithCString 转换为 NSString ,得到的结果为Âà†Èô§Â§±Ë¥•,length 是 12 ,但是字节数为 26

NSString* plain = @"删除失败";
const char *s = [plain UTF8String];
NSString* s1 = [[NSString alloc] initWithCString:s];

正确的做法当然是这样的

NSString* s2 = [[NSString alloc] initWithCString:s encoding:NSUTF8StringEncoding];

initWithCString: 是已被苹果废弃的 api ,我仍然好奇这段乱码是怎么产生的,查看文档没搞清楚它到底用的什么编码导致了这样的乱码。

4 个汉字的 utf8 字符串对应 12 个字节,乱码中的奇怪字符刚好有 12 个,好像是 1 个 utf8 字节对应一个乱码字符?有人能解惑吗

1690 次点击
所在节点    iOS
13 条回复
mainjzb
2022-06-14 11:49:07 +08:00
谷歌搜索-》 乱码恢复
mainjzb
2022-06-14 11:49:16 +08:00
mainjzb
2022-06-14 11:50:20 +08:00
所以大概率:原来编码 GBK 新编码 UTF-8
pheyer
2022-06-14 12:45:17 +08:00
@mainjzb 你看我帖子的第 2 行,跟 gbk 编码应该无关的
PolarBears
2022-06-14 14:25:42 +08:00
MrKrabs
2022-06-14 14:35:52 +08:00
s1 是 null 啊
pheyer
2022-06-14 14:44:24 +08:00
@PolarBears 这个工具不错,帮助我找到了实际的编码 NSMacOSRomanStringEncoding
NSString* s1 = [[NSString alloc] initWithCString:s];
NSString* strRoman = [[NSString alloc] initWithCString:s encoding:NSMacOSRomanStringEncoding];

以上两行代码效果相同
pheyer
2022-06-14 14:45:48 +08:00
@MrKrabs 不是 null ,你打印日志看看
MrKrabs
2022-06-14 16:39:03 +08:00
@pheyer
NSLog(@"%s %@ %@", s, s1, s2);
2022-06-14 16:37:50.533004+0800 OCString[20254:11557900] 删除失败 (null) 删除失败
pheyer
2022-06-14 16:50:08 +08:00
@MrKrabs 这还真是神奇,我用我的 Xcode13.1 的打印结果是:删除失败 Âà†Èô§Â§±Ë¥• 删除失败
用的 OS 是 MacOS 11.6 ,用 iPhone XR 测试的,难道你用的模拟器测试的?
MrKrabs
2022-06-14 17:16:49 +08:00
@pheyer 就写了个 main.m 直接在 mac 跑的
Skifary
2022-06-14 17:26:13 +08:00
字符串乱码都是编码不对造成的。const char *s 可以理解为一堆数据,至于这堆数据按照什么编码解析依靠 NSString 来指定。

initWithCString 在苹果文档里面有解释

Initializes the receiver, a newly allocated NSString object, by converting the data in a given C-string from the default C-string encoding into the Unicode character encoding.

这个函数被弃用了,在初始化的时候有一个 default C-string encoding (默认的编码)来解析这个格式。

默认的编码格式 NSString 提供了一个 defaultCStringEncoding 来获取,默认值是 30 对应的就是 NSMacOSRomanStringEncoding
Skifary
2022-06-14 17:29:01 +08:00
@Skifary 一堆 NSUTF8StringEncoding 的数据用 NSMacOSRomanStringEncoding 来解析自然就乱码了

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/859487

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX