Модераторы: Partizan, gambit

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Вопросы по Unicode, Encoding 
V
    Опции темы
Idsa
Дата 16.2.2007, 14:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник
Сообщений: 2086
Регистрация: 5.12.2006
Где: Томск

Репутация: 14
Всего: 62



1. Хотелось бы узнать, какая из Unicode-кодировок используется по умолчанию. Может, UTF16?
2. В Unicode-кодировке используемой по умолчанию в .NET, символ весит 2 байта (размер char'а). Но MSDN говорит следующее:
Цитата

UTF-8, which represents each code point as a sequence of one to four bytes.
UTF-16, which represents each code point as a sequence of one to two 16-bit integers.
UTF-32, which represents each code point as a 32-bit integer.

Т. е. фактически в MSDN говорится, что и UTF-8, и UTF-16, и UTF-32 используют 4-байтные символы. Это меня окончательно запутало smile

Это сообщение отредактировал(а) Дрон - 16.2.2007, 22:47


--------------------
Мой блог: alexidsa.blogspot.com
PM MAIL ICQ   Вверх
Gelis
Дата 16.2.2007, 14:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 145
Регистрация: 26.10.2006
Где: Брест

Репутация: 2
Всего: 4



1. Если ты о Encoding.Unicode, то это и есть UTF-16
2. а) UTF-8 кодирует некоторые символы одним байтом, некоторые двумя, а некоторые четырьмя.  1-им байтом кодируются символы английского языка, 2-мя- символы языков европейских стран, 3-мя языков восточной Азии(Япония, Китай и т.п.), 4-ый вроде для добавочных символов
    б) UTF-32-использует для кодирования 4-байта. Самый неэкономный, но самый простой для использования.
    d) UTF-16. Unicode использует 16 бит. Причем Юникод построен таким образом что один символ может состоять из одного символа и нескольких добавочных. В нем определены все символы англиеского и европейских языков, а остальные получаются с помощью добавочных.
PM MAIL   Вверх
Idsa
Дата 16.2.2007, 17:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник
Сообщений: 2086
Регистрация: 5.12.2006
Где: Томск

Репутация: 14
Всего: 62



Gelis, спасибо за подробное объяснение. Многое стало понятно. Однако возникло 4 вопроса:
1. Почему в качестве основного был выбран именно формат UTF-16, ведь самый экономный - UTF8.
2. Что будет, если переменной типа char присвоить символ, который занимает не два байта, а больше.
3. Каким образом в Unicode реализовано определение того, сколько байт занимает тот или иной символ, т. е. каким образом в потоке байтов определяется, где начинается символ и где он заканчивается.
4. При приведении переменной типа char к типу int мы получаем код в UTF-16 или UTF-32?


--------------------
Мой блог: alexidsa.blogspot.com
PM MAIL ICQ   Вверх
Gelis
Дата 16.2.2007, 18:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 145
Регистрация: 26.10.2006
Где: Брест

Репутация: 2
Всего: 4



1.UTF-8 экономнее UTF-16 тогда, когда в кодируется только английские и европейские символы, если используются какие-нить китайские бракозябры UTF для кодирования использует больше трех байт, а UTF-16 2 байта.
3. Пример из которого все понятно
Код

            StreamReader sr= new StreamReader(Stream, Encoding.GetEncoding(866));
            StreamWriter sw = new StreamWriter(Stream, Encoding.GetEncoding(866));
            string str=sr.ReadLine();

или
Код

            string str="Да здраствует Vingrad!!!";
            Encoding encASCII=Encoding.ASCII;
            byte[] encBytes=encASCII.GetBytes(str);
            ...............................................................
            string decString=encASCII.GetString(encBytes);

4. UTF-16
PM MAIL   Вверх
Idsa
Дата 17.2.2007, 17:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник
Сообщений: 2086
Регистрация: 5.12.2006
Где: Томск

Репутация: 14
Всего: 62



С 1, 3 и 4, пожалуй, разобрался (благодаря Gelis и unicode.org). А вот со вторым вопросом интересно получается... Вот что пишет MSDN:
Цитата

The char keyword is used to declare a Unicode character in the range indicated in the following table. Unicode characters are 16-bit characters used to represent most of the known written languages throughout the world (U+0000 to U+ffff).

Получается, что в .NET не предусмотрено использование всех возможностей Unicode?


--------------------
Мой блог: alexidsa.blogspot.com
PM MAIL ICQ   Вверх
mr.DUDA
Дата 17.2.2007, 17:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


3D-маньяк
****


Профиль
Группа: Экс. модератор
Сообщений: 8244
Регистрация: 27.7.2003
Где: город-герой Минск

Репутация: 110
Всего: 232



Idsa, опишите возможность, которой вам не хватает и сообщите об этом в Microsoft  smile 


--------------------
user posted image
PM MAIL WWW   Вверх
Idsa
Дата 17.2.2007, 18:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник
Сообщений: 2086
Регистрация: 5.12.2006
Где: Томск

Репутация: 14
Всего: 62



Цитата(mr.DUDA @  17.2.2007,  17:56 Найти цитируемый пост)
Idsa, опишите возможность, которой вам не хватает и сообщите об этом в Microsoft 

Ну а если серьезно? Я правильно понимаю, что в C# мы не может использовать символы, которые находятся за пределамя 2^16?


--------------------
Мой блог: alexidsa.blogspot.com
PM MAIL ICQ   Вверх
mr.DUDA
Дата 17.2.2007, 18:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


3D-маньяк
****


Профиль
Группа: Экс. модератор
Сообщений: 8244
Регистрация: 27.7.2003
Где: город-герой Минск

Репутация: 110
Всего: 232



Вы невнимательно читали на unicode.org. Что не влазит в один 16-битный char, то влазит в два:
Цитата
UTF-16 is popular in many environments that need to balance efficient access to characters with economical use of storage. It is reasonably compact and all the heavily used characters fit into a single 16-bit code unit, while all other characters are accessible via pairs of 16-bit code units.


А вообще, есть наиболее часто используемые символы, которые вынесены в первые 64K символов, то есть 16 бит хватит:
Цитата
The majority of common-use characters fit into the first 64K code points, an area of the codespace that is called the basic multilingual plane, or BMP for short.

Наверное, только мёртвые языки и особо извращённые символы потребуют более 2-х байт, но это нужно смотреть уже по юникодовским таблицам символов.

З.Ы. рассуждая логически, 1 байт явно маловато (UTF-8 только запутает со своими переменными длинами символа), 4 байт явно много, а 2 - золотая середина.


--------------------
user posted image
PM MAIL WWW   Вверх
Idsa
Дата 17.2.2007, 19:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник
Сообщений: 2086
Регистрация: 5.12.2006
Где: Томск

Репутация: 14
Всего: 62



Цитата(mr.DUDA @  17.2.2007,  18:51 Найти цитируемый пост)
Вы невнимательно читали на unicode.org. Что не влазит в один 16-битный char, то влазит в два

Читал я внимательно, но не только на unicode.org, но и в MSDN:
Цитата

The char keyword is used to declare a Unicode character in the range indicated in the following table. Unicode characters are 16-bit characters used to represent most of the known written languages throughout the world (U+0000 to U+ffff).

, так что про дополнительные 2 байта можно забыть.


Цитата(mr.DUDA @  17.2.2007,  18:51 Найти цитируемый пост)
З.Ы. рассуждая логически, 1 байт явно маловато (UTF-8 только запутает со своими переменными длинами символа), 4 байт явно много, а 2 - золотая середина.

А вот это - факт  smile. Вопрос закрыт.


--------------------
Мой блог: alexidsa.blogspot.com
PM MAIL ICQ   Вверх
Gelis
Дата 19.2.2007, 12:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 145
Регистрация: 26.10.2006
Где: Брест

Репутация: 2
Всего: 4



Цитата(Idsa @  16.2.2007,  17:13 Найти цитируемый пост)
2. Что будет, если переменной типа char присвоить символ, который занимает не два байта, а больше.

Пример C#:
Код

char c=unchecked((char)70000);//выдаст символ #65
try
{
        c=Convert.ToChar(70000);//сгенерирует исключение
}
catch(OverflowException)
{
        MessageBox.Show("Так делать низя!!!");
}

Ну и вот еще про Unicode:
а) Первый байт обычно обозначает страну, второй символы для этой страны. Например для английского языка первый байт 0, а второй совпадает с ASCII кодировкой, первый байт=1, язык - исландский...... для рашын лэнгвич первый байт-4.
б) Символ может представляться в виде. Одного символа + несколько комбинирующих комбинированые символы находятся в диапазоне 0x0300....0x0345
Например, если вывести simbol, то выведется буквачка а с черточкой вверху. Т.е. два символа обозначают один.
Код

string simbol="a\u0304";//если вывести будет а с чертой вверху
char x=simbol[0];//будет равен 'а' без черты

Кроме того в некоторых языках два подряд идущих каких-то символа обозначаются одним. Например, у немцев две подрядидущие буквы ss обозначаются одним символом, у арабов таких символов вообще немерено.
в) Проблема с китайскими языками решается с.о.: Для таких языков символ шифруется 2-мя 16-битными значениями первое называется старшим заменителем и находится в диапазоне 0xD800....0xDBFF, а второе младшим заменителем и находится соответственно в диапазоне 0xDC00........0XDFFF;
PM MAIL   Вверх
mr.DUDA
Дата 19.2.2007, 12:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


3D-маньяк
****


Профиль
Группа: Экс. модератор
Сообщений: 8244
Регистрация: 27.7.2003
Где: город-герой Минск

Репутация: 110
Всего: 232



Цитата(Gelis @  19.2.2007,  11:04 Найти цитируемый пост)
 Проблема с китайскими языками решается с.о.: Для таких языков символ шифруется 2-мя 16-битными значениями первое называется старшим заменителем и находится в диапазоне 0xD800....0xDBFF, а второе младшим заменителем и находится соответственно в диапазоне 0xDC00........0XDFFF;

о чём я и говорил выше, на что почему-то Idsa утверждает:

Цитата(Idsa @  17.2.2007,  18:33 Найти цитируемый пост)
так что про дополнительные 2 байта можно забыть.




--------------------
user posted image
PM MAIL WWW   Вверх
Idsa
Дата 19.2.2007, 15:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник
Сообщений: 2086
Регистрация: 5.12.2006
Где: Томск

Репутация: 14
Всего: 62



Хм... Может, я не так понял... Но я не очень представляю, как будет выглядеть работа с четырехбайтными символами, когда char у нас двухбайтовый. Поток байтов-то мы без проблем можем хранить... а как всю эту красоту выводить - вопрос. Насколько я понял, винда поддерживает только 16 битов Юникода. Причем в Wikipedia отмечается, что  эти 16 бит вмещают все основные языки (в том числе и восточные). Дополнительные 16 байти требуются для каких-то редко используемых восточных языков: (wikipedia)
Цитата

Поскольку в ряде компьютерных систем (например, Windows NT) уже были реализованы 16-битные символы, было решено всё наиболее важное кодировать только в пределах первых 65536 позиций (так называемая англ. Basic Multilingual Plane, BMP). Остальное пространство используется для «Дополнительных символов» (англ. Supplementary Characters): систем письма вымерших языков или очень редко используемых китайских иероглифов, математических и музыкальных символов.

И еще одна цитатка в тему:
Цитата

Большинство современных операционных систем в той или иной степени обеспечивают поддержку Юникода.
В операционных системах семейства Windows NT для внутреннего представления имён файлов и других системных строк используется двухбайтовая кодировка UTF-16LE. Системные вызовы, принимающие строковые параметры, существуют в однобайтном и двухбайтном вариантах. 

Что, на мой взгляд, подтверждает, что Винда понимает только 16-битные символы.

Возражения в студию  smile


--------------------
Мой блог: alexidsa.blogspot.com
PM MAIL ICQ   Вверх
Gelis
Дата 19.2.2007, 16:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 145
Регистрация: 26.10.2006
Где: Брест

Репутация: 2
Всего: 4



Цитата(Idsa @  19.2.2007,  15:10 Найти цитируемый пост)
Хм... Может, я не так понял... Но я не очень представляю, как будет выглядеть работа с четырехбайтными символами, когда char у нас двухбайтовый.

Char работает с двухбайтовыми числами. Извращения с комбинирующими символами и четырехбайтовыми придуманы для сравнения строк. Например, если посмотреть мой прошлый пример с символами комбинирующим символом
Цитата(Gelis @  19.2.2007,  12:04 Найти цитируемый пост)

string simbol="a\u0304";//если вывести будет а с чертой вверху    

Допустим в какой-то культуре ,например у племени тумба-юмба, есть стандартный символ а с чертой вверху. То для этой культуры строка simbol и строка состоящая из а с черточкой вверху будут равны.
Комбинирующие символы нужны для того, чтобы нам не рыться по таблицам Unicode-символов, а при необходимости самим получить этот символ с помощью комбинирующих.
Аналогичная ситуация и с символами, которые в сочетании в нескольких языках обозначают один. Например, для немецкой культуры строка состоящая из двух символов ss, будет равна какой-то строке содержащей один символ напоминающий греческую букву бетта. Т.е. для некоторой культуры несколько 16-битных символов могут обозначать один символ, хотя есть  и символ который для этой культуры обозначается одним 16-битным числом.
По-поводу китайских языков в которых больше иероглифов чем даже может содержать 16бит. Для них применяется специальный диапазон символов

Цитата(Gelis @  19.2.2007,  12:04 Найти цитируемый пост)
Для таких языков символ шифруется 2-мя 16-битными значениями первое называется старшим заменителем и находится в диапазоне 0xD800....0xDBFF, а второе младшим заменителем и находится соответственно в диапазоне 0xDC00........0XDFFF;

Так как я не силен в 16-разрядной арифметике, лишь предположу что просто проверяется бит(так как первая четверка бит-D) установленый в первом байте и исходя из этого один иероглиф считается равным двум символам.

Цитата(Idsa @  19.2.2007,  15:10 Найти цитируемый пост)
Что, на мой взгляд, подтверждает, что Винда понимает только 16-битные символы.


Она и понимает 16-битные, но что ей мешает, при рисовании одной буквы использовать два символа?
Просто иероглиф отображается на экран одним символом, а на самом деле состоит из двух.
PM MAIL   Вверх
mr.DUDA
Дата 19.2.2007, 17:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


3D-маньяк
****


Профиль
Группа: Экс. модератор
Сообщений: 8244
Регистрация: 27.7.2003
Где: город-герой Минск

Репутация: 110
Всего: 232



Idsa, что не понятно ? Берёшь два соседних char-а и говоришь "это один символ, из двух 16-битных половинок". Можешь его в int положить для сравнений, а можешь string-и напрямую сравнивать - и сравнение будет работать корректно.


--------------------
user posted image
PM MAIL WWW   Вверх
Idsa
Дата 19.2.2007, 19:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник
Сообщений: 2086
Регистрация: 5.12.2006
Где: Томск

Репутация: 14
Всего: 62



Ну всё! Уговорили smile


--------------------
Мой блог: alexidsa.blogspot.com
PM MAIL ICQ   Вверх
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
mr.DUDA
THandle

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.
Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :)
Так же не забывайте отмечать свой вопрос решенным, если он таковым является :)


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, THandle.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Общие вопросы по .NET и C# | Следующая тема »


 




[ Время генерации скрипта: 0.0573 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.