Нахождение, какие кодировки в .NET совместимы с ASCII

c# .net encoding ascii

505 просмотра

1 ответ

Есть ли на самом деле какой-либо простой метод определения того, какие кодировки в .NET совместимы с ASCII?

(На основании вопроса, заданного в комментарии Ниргуда .)

Автор: Douglas Источник Размещён: 08.11.2019 11:08

Ответы (1)


1 плюс

Решение

Мы примем стандартное определение ASCII, которое ограничено 128 символами (а именно значениями байтов, старший бит которых равен 0). Unicode был спроектирован так, что его первые 128 кодовых точек соответствуют их эквивалентам ASCII. Поскольку числовое значение charструктуры в .NET соответствует ее кодовой точке Unicode (за исключением суррогатов), мы можем определить вспомогательный метод следующим образом:

private static readonly byte[] asciiValues = 
    Enumerable.Range(0, 128).Select(b => (byte)b).ToArray();

private static readonly string asciiChars = 
    new string(asciiValues.Select(b => (char)b).ToArray());

public static bool IsAsciiCompatible(Encoding encoding)
{
    try
    {
        return encoding.GetString(asciiValues).Equals(asciiChars, StringComparison.Ordinal)
            && encoding.GetBytes(asciiChars).SequenceEqual(asciiValues);
    }
    catch (ArgumentException)
    {
        // Encoding.GetString may throw DecoderFallbackException if a fallback occurred 
        // and DecoderFallback is set to DecoderExceptionFallback.
        // Encoding.GetBytes may throw EncoderFallbackException if a fallback occurred 
        // and EncoderFallback is set to EncoderExceptionFallback.
        // Both of these derive from ArgumentException.
        return false;
    }
}

Затем мы могли бы перечислить все кодировки .NET следующим образом:

var encodings = Encoding.GetEncodings().Select(e => e.GetEncoding()).ToList();
var asciiCompatible = encodings.Where(e => IsAsciiCompatible(e)).ToList();
var nonAsciiCompatbile = encodings.Except(asciiCompatible).ToList();

Console.WriteLine("ASCII compatible: ");
foreach (var encodingName in asciiCompatible.Select(e => e.EncodingName).OrderBy(n => n))
    Console.WriteLine("* " + encodingName);
Console.WriteLine();
Console.WriteLine("Non-ASCII compatible: ");
foreach (var encodingName in nonAsciiCompatbile.Select(e => e.EncodingName).OrderBy(n => n))
    Console.WriteLine("* " + encodingName);

Обратите внимание, что этот метод не совсем безопасен. Если существует многобайтовая кодировка, которая выполняет причудливое отображение последовательных байтов или символов - например, декодирование 0x61в 'a'и 0x62в 'b'(как в ASCII), но 0x6261в "�"- тогда этот тест даст неверные результаты.

Запуск этого в .NET Fiddle ( фрагмент ) дает следующие результаты:

ASCII совместимый:

  • Арабский (864)
  • Арабский (ASMO 708)
  • Арабский (DOS)
  • Арабский (ISO)
  • Арабский (Mac)
  • Арабский (Windows)
  • Балтика (ДОС)
  • Балтика (ИСО)
  • Балтика (Windows)
  • Центрально-Европейский (DOS)
  • Центрально-Европейский (ISO)
  • Центрально-Европейский (Mac)
  • Центральноевропейский (Windows)
  • Упрощенный китайский (EUC)
  • Упрощенный китайский (GB18030)
  • Упрощенный китайский (GB2312)
  • Упрощенный китайский (GB2312-80)
  • Упрощенный китайский (ISO-2022)
  • Китайский упрощенный (Mac)
  • Китайский традиционный (Big5)
  • Китайский традиционный (ЦНС)
  • Китайский традиционный (этен)
  • Китайский традиционный (Mac)
  • Хорватский (Mac)
  • Кириллица (дос)
  • Кириллица (изо)
  • Кириллица (KOI8-R)
  • Кириллица (KOI8-U)
  • Кириллица (Mac)
  • Кириллица (Windows)
  • Эстонский (ISO)
  • Французский канадский (DOS)
  • Греческий (DOS)
  • Греческий (ISO)
  • Греческий (Mac)
  • Греческий (Windows)
  • Греческий, современный (DOS)
  • Иврит (дос)
  • Иврит (ISO-Logical)
  • Иврит (ISO-визуальный)
  • Иврит (Mac)
  • Иврит (Windows)
  • IBM5550 Тайвань
  • Исландский (DOS)
  • Исландский (Mac)
  • ISCII Ассамский
  • ISCII бенгальский
  • ISCII Деванагари
  • ISCII гуджарати
  • ISCII Каннада
  • ISCII малаялам
  • ISCII Ория
  • ISCII панджаби
  • ISCII тамильский
  • ISCII телугу
  • Японский (EUC)
  • Японский (JIS 0208-1990 и 0212-1990)
  • Японский (Mac)
  • Японский (Shift-JIS)
  • Корейский
  • Корейский (EUC)
  • Корейский (йохаб)
  • Корейский (Mac)
  • Корейский Wansung
  • Латинская 3 (ISO)
  • Латинская 9 (ISO)
  • Нордический (DOS)
  • OEM кириллица
  • OEM многоязычная латынь I
  • OEM США
  • Португальский (DOS)
  • Румынский (Mac)
  • TCA Тайвань
  • ТелеТекст Тайвань
  • Тайский (Windows)
  • Турецкий (DOS)
  • Турецкий (ISO)
  • Турецкий (Mac)
  • Турецкий (Windows)
  • Украинский (Mac)
  • Юникод (UTF-8)
  • US-ASCII
  • Вьетнамский (Windows)
  • Ван Тайвань
  • Западноевропейский (DOS)
  • Западноевропейский (ISO)
  • Западноевропейский (Mac)
  • Западноевропейский (Windows)

Не ASCII-совместимый:

  • Китайский упрощенный (HZ)
  • Europa
  • Немецкий (IA5)
  • IBM EBCDIC (арабский)
  • IBM EBCDIC (кириллица русский)
  • IBM EBCDIC (кириллица, сербско-болгарский)
  • IBM EBCDIC (Дания-Норвегия)
  • IBM EBCDIC (Дания-Норвегия-Евро)
  • IBM EBCDIC (Финляндия-Швеция)
  • IBM EBCDIC (Финляндия-Швеция-Евро)
  • IBM EBCDIC (Франция)
  • IBM EBCDIC (Франция-Евро)
  • IBM EBCDIC (Германия)
  • IBM EBCDIC (Германия-Евро)
  • IBM EBCDIC (греческий модерн)
  • IBM EBCDIC (греческий)
  • IBM EBCDIC (иврит)
  • IBM EBCDIC (исландский)
  • IBM EBCDIC (Исландский-Евро)
  • IBM EBCDIC (международный)
  • IBM EBCDIC (Международный-Евро)
  • IBM EBCDIC (Италия)
  • IBM EBCDIC (Италия-Евро)
  • IBM EBCDIC (японская катакана)
  • IBM EBCDIC (корейский расширенный)
  • IBM EBCDIC (многоязычная латиница-2)
  • IBM EBCDIC (Испания)
  • IBM EBCDIC (Испания-Евро)
  • IBM EBCDIC (тайский)
  • IBM EBCDIC (турецкая латынь-5)
  • IBM EBCDIC (турецкий)
  • IBM EBCDIC (Великобритания)
  • IBM EBCDIC (Великобритания-Евро)
  • IBM EBCDIC (США-Канада)
  • IBM EBCDIC (США-Канада-Евро)
  • IBM Latin-1
  • IBM Latin-1
  • ISO-6937
  • Японский (JIS)
  • Японский (JIS-Allow 1 байта Кана - SO / SI)
  • Японский (JIS-Allow 1 байта кана)
  • Корейский (ISO)
  • Норвежский (IA5)
  • Шведский (IA5)
  • T.61
  • Тайский (Mac)
  • Юникод (UTF-16)
  • Unicode (Big-Endian)
  • Юникод (UTF-32 Big-Endian)
  • Юникод (UTF-32)
  • Юникод (UTF-7)
  • Западноевропейский (IA5)
Автор: Douglas Размещён: 20.08.2016 09:46
32x32