有没有ASCII扩展编码的列表?

3
我需要根据已知的文件编码和所需的输出编码来决定是否(不)转换文本文件。
如果文本是US-ASCII,则在输出编码为ASCII,UTF-8,Latin1等时无需转换。显然,我需要将US-ASCII文件转换为UTF-16或UTF-32。
标准编码列表位于http://www.iana.org/assignments/character-sets/character-sets.xml
如果满足以下条件,则需要转换:
- 最小字符大小> 1字节或 - 前127个代码点与US-ASCII不同。
我想知道:
- 是否有类似的列表,其中包含有关每种编码实现的详细信息(字节长度,ASCII兼容性)?
- 我希望有一个仅包含 Qt5支持的编解码器的列表。

编辑
我已经找到了问题的答案

  • 所有基于8位或可变8位的编解码器是否都是ASCII的超集?
    • 换句话说:US-ASCII可以被解释为任何基于8位或可变8位的编码吗?

在这里找到答案:不是ASCII超集的字符集
相反,了解以下信息会很有帮助:

  • 是否有ASCII的超集字符集列表?

这看起来很有前途:
mime.charsets - ASCII超集的字符集列表,
但我找不到实际的mime.charsets文件。


1
你想要这个纯粹只是为了决定是否需要进行转换吗?为什么不直接进行转换呢;如果不需要更改任何内容,那就什么也不会发生。我不太明白在什么情况下会有用到这样的东西。 - deceze
@deceze 我将一堆文件转换并替换旧文件。我不想触碰不需要转换的文件。听起来合理吗? - Martin Hennings
1
将它们转换一下,测试是否与原始内容相同,如果是,则丢弃转换后的内容。听起来对我来说简单多了。 - deceze
@deceze 我认为我们应该回到最初的问题:“是否有ASCII的超集字符集列表?” - Martin Hennings
1个回答

3

另一种方法是以给定编码方式解码字节 0x00 - 0x7F,并检查字符是否与 ASCII 匹配。例如,在 Python 3.x 中:

def is_ascii_superset(encoding):
    for codepoint in range(128):
       if bytes([codepoint]).decode(encoding, 'ignore') != chr(codepoint):
           return False
    return True

这将会得到以下结果:
>>> is_ascii_superset('US-ASCII')
True
>>> is_ascii_superset('windows-1252')
True
>>> is_ascii_superset('ISO-8859-15')
True
>>> is_ascii_superset('UTF-8')
True
>>> is_ascii_superset('UTF-16')
False
>>> is_ascii_superset('IBM500') # a variant of EBCDIC
False

编辑:在C++中为您的Qt版本支持的每种编码获取US-ASCII兼容性:

#include <QTextCodec>
#include <QMap>

typedef enum
{
    eQtCodecUndefined,
    eQtCodecAsciiIncompatible,
    eQtCodecAsciiCompatible,
} tQtCodecType;

QMap<QByteArray, tQtCodecType> QtCodecTypes()
{
    QMap<QByteArray, tQtCodecType> CodecTypes;
    // How to test Qt's interpretation of ASCII data?
    QList<QByteArray> available = QTextCodec::availableCodecs();
    QTextCodec *referenceCodec = QTextCodec::codecForName("UTF-8"); // because Qt has no US-ASCII, but we only test bytes 0-127 and UTF-8 is a superset of US-ASCII
    if(referenceCodec == 0)
    {
        qDebug("Unable to get reference codec 'UTF-8'");
        return CodecTypes;
    }
    for(int i = 0; i < available.count(); i++)
    {
        const QByteArray name = available.at(i);
        QTextCodec *currCodec = QTextCodec::codecForName(name);
        if(currCodec == NULL)
        {
            qDebug("Unable to get codec for '%s'", qPrintable(QString(name)));
            CodecTypes.insert(name, eQtCodecUndefined);
            continue;
        }
        tQtCodecType type = eQtCodecAsciiCompatible;
        for(uchar j = 0; j < 128; j++) // UTF-8 == US-ASCII in the lower 7 bit
        {
            const char c = (char)j; // character to test < 2^8
            QString sRef, sTest;
            sRef = referenceCodec->toUnicode(&c, 1); // convert character to UTF-16 (QString internal) assuming it is ASCII (via UTF-8)
            sTest = currCodec->toUnicode(&c, 1); // convert character to UTF-16 assuming it is of type [currCodec]
            if(sRef != sTest) // compare both UTF-16 representations -> if they are equal, these codecs are transparent for Qt
            {
                type = eQtCodecAsciiIncompatible;
                break;
            }
        }
        CodecTypes.insert(name, type);
    }

    return CodecTypes;
}

你说得对,想一想,成为ASCII超集的标准非常简单,所以我可以自己创建那个列表 - 一旦它工作了,我会将我的C++实现添加到你的答案中以供参考。 - Martin Hennings
哦,非常有趣的解决方案。只需检查我所获得的编码的前128个字节,就像检查它是否与列表相匹配一样容易。 - Nyerguds

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接