关于iconv将iso-8859-1转UTF-8乱码及反向转换异常的疑问
编码转换异常的原因拆解
核心问题:初始编码判断错误
你一开始就搞错了原文件的编码——原文件实际是UTF-8,不是ISO-8859-1。ISO-8859-1编码里根本没有≈这个字符,你看到的乱码:
≈kersberga
其实是终端用ISO-8859-1编码解析UTF-8格式的Åkersberga时出现的问题:UTF-8中Å的字节是0xC3 0xA5,用ISO-8859-1读会拆成两个独立字符,显示成≈(具体符号取决于终端字体)。
第一次错误转换的后果
你用以下脚本转换时:
for file in ~/blabla/* do echo "${file}" iconv -f iso-8859-1 -t UTF-8 "${file}" > "${file}.tmp" rm "${file}" mv "${file}.tmp" "${file}" done
相当于把UTF-8文件的每个字节都当成ISO-8859-1的单个字符,再重新编码成UTF-8:
- 原UTF-8中
Å的两个字节0xC3和0xA5,被当成ISO-8859-1的Ã和… - 这两个字符转成UTF-8后,变成了
0xC3 0x83和0xC2 0xA5,所以最终文件内容变成:
Ã…kersberga
且文件编码为UTF-8。
反向转换为何“修复”了显示
执行反向转换脚本:
for file in ~/blabla/* do echo "${file}" iconv -f UTF-8 -t iso-8859-1 "${file}" > "${file}.tmp" rm "${file}" mv "${file}.tmp" "${file}" done
本质是把错误转换后的UTF-8字符再转成ISO-8859-1字节:
Ã转成ISO-8859-1的0xC3,…转成0xA5- 最终文件的字节序列又变回了
0xC3 0xA5,也就是UTF-8格式的Å - 此时
file -b --mime-encoding检测为UTF-8,是因为0xC3 0xA5本身就是合法的UTF-8字节序列,而ISO-8859-1和UTF-8在单字节范围内有重叠,file会优先判定为UTF-8。当终端用UTF-8编码显示时,自然就能正确显示:
Åkersberga
总结
整个过程是两次错误编码操作的意外抵消:第一次把UTF-8误判为ISO-8859-1转成UTF-8,第二次又把这个错误的UTF-8转成ISO-8859-1,刚好还原了原文件的字节序列,让终端能正确解析。
内容的提问来源于stack exchange,提问作者14mble
相关产品推荐
相关产品推荐

