首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >“原”从双UTF-8转换为UTF-8 (或从UTF-8转换为ANSI)

“原”从双UTF-8转换为UTF-8 (或从UTF-8转换为ANSI)
EN

Stack Overflow用户
提问于 2014-05-14 13:45:34
回答 2查看 3.2K关注 0票数 2

我正在处理一个使用UTF-8编码两次的遗留文件。例如,编码点ε (U+03B5)应该被编码为CE B5,但是已经被编码为C3 8E C2 B5 (CE 8EU+00CE的UTF-8编码,C2 B5U+00B5的UTF-8编码)。

假设数据是在CP-1252中编码的,则执行第二次编码。

要返回UTF-8编码,我使用以下命令(似乎错误)

代码语言:javascript
运行
复制
iconv --from utf8 --to cp1252 <file.double-utf8 >file.utf8

我的问题是,偶像似乎无法转换回一些字符。更准确地说,康涅夫无法转换其UTF-8表示包含映射到CP-1252中的控制字符的字符的字符。一个例子是代码点ρ (U+03C1):

  • 它的UTF-8编码是CF 81
  • 第一个字节CF被重新编码为C3 8F
  • 第二个字节81被重新编码为C2 81

康视拒绝将C2 81转换回81,可能是因为它不知道如何精确地映射该控制字符。

代码语言:javascript
运行
复制
echo -e -n '\xc3\x8f\xc2\x81' | iconv --from utf8 --to cp1252
�iconv: illegal input sequence at position 2

,我怎么能不关心映射,只执行数学的UTF-8转换?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-06-11 11:50:22

下面的代码使用Ruby的低级别编码函数强制将双编码UTF-8 (从CP1525)重写为普通UTF-8。

代码语言:javascript
运行
复制
#!/usr/bin/env ruby

ec = Encoding::Converter.new(Encoding::UTF_8, Encoding::CP1252)

prev_b = nil

orig_bytes = STDIN.read.force_encoding(Encoding::BINARY).bytes.to_a
real_utf8_bytes = ""
real_utf8_bytes.force_encoding(Encoding::BINARY)

orig_bytes.each_with_index do |b, i|
    b = b.chr

    situation = ec.primitive_convert(b.dup, real_utf8_bytes, nil, nil, Encoding::Converter::PARTIAL_INPUT)

    if situation == :undefined_conversion
            if prev_b != "\xC2"
                    $stderr.puts "ERROR found byte #{b.dump} in stream (prev #{(prev_b||'').dump})"
                    exit
            end

            real_utf8_bytes.force_encoding(Encoding::BINARY)
            real_utf8_bytes << b
            real_utf8_bytes.force_encoding(Encoding::CP1252)
    end

    prev_b = b
end

real_utf8_bytes.force_encoding(Encoding::BINARY)
puts real_utf8_bytes

它用于管道:

代码语言:javascript
运行
复制
cat $PROBLEMATIC_FILE | ./fix-double-utf8-encoding.rb > $CORRECTED_FILE
票数 0
EN

Stack Overflow用户

发布于 2014-05-15 10:49:51

代码语言:javascript
运行
复制
echo -e -n '\xc3\x8f\xc2\x81' | iconv --from utf8 --to iso8859-1

在0x80-0x9F范围内,Windows1252不同于ISO-8859-1。例如,在您的例子中,0x81在ISO8859-1中是U+0081,但在Windows1252中是无效的。

检查其他数据是否被误解为Windows1252或ISO 8859-1.通常,ISO 8859-1是比较常见的.

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23656466

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档