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 と同じではありません。

知りたい:


編集
私はすでに質問への答えを見つけました

  • すべての 8 または可変 8 ビット ベースのコーデックは ASCII のスーパーセットですか?
    • 言い換えれば、US-ASCII は 8 または可変 8 ビットベースのエンコーディングとして解釈できますか?

ここ: ASCII のスーパーセットではない文字
セット

  • ASCII のスーパーセットである文字セットのリストはありますか?

これは有望に見えます:
mime.charsets - list of character sets which are ASCII supersets ですが、
実際の mime.charsets ファイルが見つかりませんでした。

4

1 に答える 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;
}
于 2013-10-30T22:43:18.443 に答える