【问题标题】:Is there a list of ASCII-extending encodings?是否有 ASCII 扩展编码列表?
【发布时间】:2013-11-09 22:05:54
【问题描述】:

我需要根据已知的文件编码和所需的输出编码来决定何时(不)转换文本文件。

如果文本是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 兼容性)?

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

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

这里:Character set that is not a superset of ASCII
相反,了解以下信息会有所帮助:

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

这看起来很有希望:
mime.charsets - list of character sets which are ASCII supersets,
但我找不到实际的 mime.charsets 文件。

【问题讨论】:

  • 您希望这纯粹是为了决定某些东西是否需要转换?为什么不简单地进行转换;如果什么都不需要改变,什么都不会发生。不太明白这样的事情在什么情况下会有用。
  • @deceze 我转换了一堆文件替换旧文件。我不想碰那些不需要转换的文件。听起来合理吗?
  • 如何转换它们,测试它们是否与原始版本相同,如果是则放弃转换?对我来说听起来要简单得多。
  • @deceze 我认为我们应该回到最初的问题“是否存在作为 ASCII 超集的字符集列表?”

标签: character-encoding ascii


【解决方案1】:

另一种方法是解码给定编码中的字节 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

编辑:为您的 Qt 版本在 C++ 中支持的每种编码获取 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++ 实现添加到您的答案中以供进一步参考尽快生效。
  • 哦,非常有趣的解决方案。只需检查我得到的编码的前 128 个字节,就像检查一个列表一样简单。
猜你喜欢
  • 2020-01-19
  • 1970-01-01
  • 1970-01-01
  • 2011-06-05
  • 2014-02-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-25
相关资源
最近更新 更多