使用libiconv而不是iconv二进制文件时,为什么会得到不同的结果?

时间:2015-08-04 13:32:14

标签: c go iconv libiconv

以下是我在UCS-2中编码的示例字符串:

abvgdđežzijklmnjoprstćuvhcčdžš1234567890*+;'

将UCS-2转换为iso ISO-8859-1 //带有iconv二进制文件的TRANSLIT从文件到文件时,我得到:

abvgd?ezzijklmnjoprstcuvhccdzs1234567890*+;'

现在我想在go项目中使用libiconv。我使用这个库github.com/qiniu/iconv作为libiconv的绑定。但是当我使用绑定时,我得到了:

abvgd?e?zijklmnjoprst?uvhc?d??1234567890*+;'

在go中使用库时,就像使用不同的音译规则一样。

我检查了绑定库,一切看起来都是有序的;只传递字节,因此不会发生“信息丢失”。

使用libiconv时还有其他我应该注意的事项吗?是否存在一些可能触发不同音译行为的环境背景?

EDIT(关于调用的其他说明):

我有两个文件“ucs-2.txt”和“latin1.txt”。 ucs-2.txt文件包含UCS-2编码的字符串,latin1.txt包含通过运行得到的字符串:

iconv -f UCS2 -t ISO-8859-1//TRANSLIT --verbose data/encoding/ucs-2.txt > data/encoding/latin1.txt

在go中我使用这些行来从这些文件中提取内容:

var err error
ucs2, err = ioutil.ReadFile("data/encoding/ucs-2.txt")
if err != nil {
    log.Fatal(err)
}
latin1, err = ioutil.ReadFile("data/encoding/latin1.txt")
if err != nil {
    log.Fatal(err)
}

此功能正在进行转换:

func convertEnc(content []byte) ([]byte, error) {
    cd, err := iconv.Open("ISO-8859-1//TRANSLIT", "UCS2")
    if err != nil {
        return nil, err
    }
    defer cd.Close()
    var outbuf [255]byte
    res, _, err := cd.Conv(content, outbuf[:])
    log.Printf("result: %+q", res)
    return res, err
}

我正在使用DeepEqual进行测试:

reflect.DeepEqual(res, latin1)

2 个答案:

答案 0 :(得分:2)

第一个输出包括音译,即某些字符(例如ž)被音译成不完全正确的“普通”对应物(z),以便可以在编码中表示不支持原始字符(此处为Latin-1中的ž)。

第二个输出没有音译任何内容,它删除了目标编码中无法表示的任何字符(žć,...在Latin-1中。

因此,我怀疑你可以使用与库不同的选项。不熟悉libiconv,似乎//TRANSLIT部分被忽略或者您使用的函数不支持...?

答案 1 :(得分:1)

音译取决于语言环境。可能是你的libiconv缺乏/有错误的语言环境。或者您在那里使用的语言环境没有配置音译。

请检查this bug report,因为它有一些示例和关于此主题的讨论。