powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / TEncoding и его потомки
22 сообщений из 22, страница 1 из 1
TEncoding и его потомки
    #39531002
Может кто-нибудь на пальцах объяснить откуда взялись формулы в следующих методах:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
function TUTF8Encoding.GetMaxByteCount(CharCount: Integer): Integer;
begin
  Result := (CharCount + 1) * 3;
end;

function TUnicodeEncoding.GetMaxByteCount(CharCount: Integer): Integer;
begin
  Result := (CharCount + 1) * 2;
end;

function TUTF7Encoding.GetMaxByteCount(CharCount: Integer): Integer;
begin
  Result := (CharCount * 3) + 2;
end;

function TMBCSEncoding.GetMaxByteCount(CharCount: Integer): Integer;
begin
  Result := (CharCount + 1) * FMaxCharSize;
end;


Я могу понять только формулу в TUTF7Encoding, происхождение остальных для меня является загадкой.
Скопировано из XE7, возможно в других версиях другие формулы.
...
Рейтинг: 0 / 0
TEncoding и его потомки
    #39531024
Фотография Dmitry Arefiev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Какие вопросы ставил перед собой и как на них отвечал ?
Или вопросы не ставил, в виду ..., и ответ праздо нужен ?
...
Рейтинг: 0 / 0
TEncoding и его потомки
    #39531061
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dmitry Arefiev,

Вот, кстати, мне тоже стало [праздно] интересно, откуда взялись первая и третья формулы?.. :)
(автор темы не я)
...
Рейтинг: 0 / 0
TEncoding и его потомки
    #39531082
white_nigger
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alekcvp, можете глянуть на комментарии в дотнете
UTF8
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
        public override int GetMaxByteCount(int charCount)
        {
            if (charCount < 0)
               throw new ArgumentOutOfRangeException("charCount",
                    Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
            Contract.EndContractBlock();

            // Characters would be # of characters + 1 in case left over high surrogate is ? * max fallback
            long byteCount = (long)charCount + 1;

            if (EncoderFallback.MaxCharCount > 1)
                byteCount *= EncoderFallback.MaxCharCount;

            // Max 3 bytes per char.  (4 bytes per 2 chars for surrogates)
            byteCount *= 3;

            if (byteCount > 0x7fffffff)
                throw new ArgumentOutOfRangeException("charCount", Environment.GetResourceString("ArgumentOutOfRange_GetByteCountOverflow"));

            return (int)byteCount;
        }



UTF7
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
        public override int GetMaxByteCount(int charCount)
        {
            if (charCount < 0)
               throw new ArgumentOutOfRangeException("charCount",
                    Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
            Contract.EndContractBlock();

            // Suppose that every char can not be direct-encoded, we know that
            // a byte can encode 6 bits of the Unicode character.  And we will
            // also need two extra bytes for the shift-in ('+') and shift-out ('-') mark.
            // Therefore, the max byte should be:
            // byteCount = 2 + Math.Ceiling((double)charCount * 16 / 6);
            // That is always <= 2 + 3 * charCount;
            // Longest case is alternating encoded, direct, encoded data for 5 + 1 + 5... bytes per char.
            // UTF7 doesn't have left over surrogates, but if no input we may need an output - to turn off
            // encoding if MustFlush is true.

            // Its easiest to think of this as 2 bytes to turn on/off the base64 mode, then 3 bytes per char.
            // 3 bytes is 18 bits of encoding, which is more than we need, but if its direct encoded then 3
            // bytes allows us to turn off and then back on base64 mode if necessary.

            // Note that UTF7 encoded surrogates individually and isn't worried about mismatches, so all
            // code points are encodable int UTF7.
            long byteCount = (long)charCount * 3 + 2;

            // check for overflow
            if (byteCount > 0x7fffffff)
                throw new ArgumentOutOfRangeException("charCount", Environment.GetResourceString("ArgumentOutOfRange_GetByteCountOverflow"));

            return (int)byteCount;
        }
...
Рейтинг: 0 / 0
TEncoding и его потомки
    #39531608
white_niggeralekcvp, можете глянуть на комментарии в дотнете
UTF8
Прочитал комментарии для UTF8 в дотнете и так и не понял почему 1 символ максимально занимает 6 байт, в то время как сейчас по стандарту максимальный размер одного символа 4 байта в UTF8. Если отталкиваться от UTF16 (с суррагатными парами, которые расширяют интервал до 20бит), то 1 символ всегда занимает 3 байта и только если это суррогатная пара - то 4 байта, но суррогатная пара это уже 2 символа, которые будут занимать 6 байт если это будут не суррогатные символы. Т.е. TUTF8Encoding.GetMaxByteCount всегда возвращает длину на 3 байта больше чем может быть в реальности. Если же отталкиваться от UTF32, то функция возвращает всегда меньше чем может занимать строка в реальности.
...
Рейтинг: 0 / 0
TEncoding и его потомки
    #39531615
Няшик
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Праздный интерес,

В Википедии же всё написано
https://ru.wikipedia.org/wiki/UTF-8

1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
...
Рейтинг: 0 / 0
TEncoding и его потомки
    #39531659
Няшик,

Именно википедией и пользовался, вот только в моих расчетах максимальный размер строки в байтах получается иной чем (CharCount + 1) * 3.

ориентируемся на UTF16:
1 символ - всегда 3 байта (16 бит - 3 байта), суррогатная пара на то и суррогатная в 1 символ не вмещается
2 символа - либо 6 байт, для простых символов, либо 4, если суррогатная пара

как можно заметить расчет по формуле всегда дает максимальны размер на 3 байта длиннее.

ориентируемся на UTF32:
1 символ - 6 байт, но это не точно, ведь это только для 31бита
2 символа - 12 байт

по формуле только размер 1 символа совпадает, дальше же он с каждым разом все больше и больше отстаёт.

Я прошу показать где я ошибся в расчетах.
...
Рейтинг: 0 / 0
TEncoding и его потомки
    #39531675
MKZM
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А в чем проблема?
...
Рейтинг: 0 / 0
TEncoding и его потомки
    #39531691
s62
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Праздный интерес,
в тексте с .NET этого нет, но может дело в BOM. 3 байта для UTF8, 2 байта для UTF-16. Как раз получается, как в функциях.
...
Рейтинг: 0 / 0
TEncoding и его потомки
    #39531739
white_nigger
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Праздный интересНяшик,
ориентируемся на UTF16:
1 символ - всегда 3 байта (16 бит - 3 байта), суррогатная пара на то и суррогатная в 1 символ не вмещается
2 символа - либо 6 байт, для простых символов, либо 4, если суррогатная параМесье надо подтянуть матчасть
Суррогатная пара - это и есть ОДИН символ, который в UTF16 кодируется четырьмя байтами (два WideChar), а в UTF8 шестью байтами
...
Рейтинг: 0 / 0
TEncoding и его потомки
    #39531775
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
white_niggerСуррогатная пара - это и есть ОДИН символ, который в UTF16 кодируется четырьмя байтами (два WideChar), а в UTF8 шестью байтами
Суррогатная пара и в UTF-8 кодируется четырьмя байтами (максимальный кодпоинт юникода 10FFFF). Теоретически схема кодирования UTF-8 допускает 6-байтовые последовательности, но стандартом закреплены только 4-байтовые максимум.
...
Рейтинг: 0 / 0
TEncoding и его потомки
    #39531785
white_nigger
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Kazantsev AlexeyСуррогатная пара и в UTF-8 кодируется четырьмя байтами (максимальный кодпоинт юникода 10FFFF). Теоретически схема кодирования UTF-8 допускает 6-байтовые последовательности, но стандартом закреплены только 4-байтовые максимумНу так мелкомягкие и пишут интересно:
сначала "Characters would be # of characters + 1 in case left over high surrogate", что их может быть два, а потом
не парясь " Max 3 bytes per char."
Хотя и замечают, как ты сказал "(4 bytes per 2 chars for surrogates)"

Я так понимаю, что никто не парится, раз допускается - значит max считают = 6
...
Рейтинг: 0 / 0
TEncoding и его потомки
    #39531786
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
white_niggerЯ так понимаю, что никто не парится, раз допускается - значит max считают = 6
Нет, они не парятся и за Max считают = 3...
...
Рейтинг: 0 / 0
TEncoding и его потомки
    #39531789
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
white_niggerЯ так понимаю, что никто не парится, раз допускается - значит max считают = 6
Я не понял из чего ты делаешь вывод о 6. У них, как раз, расчёт делается на то что, один кодпоинт из BMP это всегда 3 байта, а суррогатная пара представленная двумя такими кодпоинтами и кодирующаяся 4 байтами по любому влезет в 6 байт для двух обычных кодпоинтов.

// Characters would be # of characters + 1 in case left over high surrogate is ? * max fallback
Вот это, мне кажется, вообще ошибка. Тут, насколько я понимаю, говорится о возможном наличии одиночного старшего суррогата в конце строки (разделённая суррогатная пара) из-за чего будет задействоваться фолбек, который, как они считают (судя по комментарию), всегда 3 байта.
Но тут возникает пара вопросов:
1. Если max fallback принят за 3 байта (а дефолтный replacement char в UTF-8 представляется именно 3 байтами), то нафига делать +1, ведь и нормальный кодпоинт из BMP по максимуми кодируется 3 байтами.
2. Какого фига max fallback принят за 3 байта, когда EncoderReplacementFallback можно инициализировать любой строкой, и он будет возвращать столько байт сколько хочется.
В общем, или это ошибка или я не понимаю механизм работы фолбека в дотнете.

p.s. Ну а дельфийские енкодерописатели тупо собезьянили дотнетовский код, вот и всё объяснение (потеряв фолбеки по пути).
...
Рейтинг: 0 / 0
TEncoding и его потомки
    #39531796
white_nigger
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Kazantsev AlexeyЯ не понял из чего ты делаешь вывод о 6
Думаю чтобы полностью кодировать UCS-4
Kazantsev Alexeyp.s. Ну а дельфийские енкодерописатели тупо собезьянили дотнетовский код, вот и всё объяснение (потеряв фолбеки по пути).Именно! (аналоги фолбеков пришлось писать для нашего рича)
PS:
Юникодная таблица вещь весьма непостоянная. Если в неё добавляют таккую хню как алхимические символы, то возможно когда-нить будет мало диаппазона 0-10FFFF
...
Рейтинг: 0 / 0
TEncoding и его потомки
    #39531799
white_nigger
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А может и правда MS облажалась, а не думала о совместимости с будущим UNICODE и максимально возможной последовательности для UTF8
...
Рейтинг: 0 / 0
TEncoding и его потомки
    #39531802
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
white_niggerДумаю чтобы полностью кодировать UCS-4
UCS-4 это та же UTF-32, то есть форма представления юникода, а он ограничен 0-10FFFF.

white_niggerИменно! (аналоги фолбеков пришлось писать для нашего рича)
Аналогичная фигня...

white_niggerто возможно когда-нить будет мало диаппазона 0-10FFFF
Это вряд ли. UTF-16 не сможет кодировать всё что выше этого, а на неё слишком много всего завязано.
...
Рейтинг: 0 / 0
TEncoding и его потомки
    #39531803
white_nigger
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
И всё таки они убеждены
MaxByteSequenceLen = 6; // max bytes per character
Это из реализации ридера Xml .NET Framework
...
Рейтинг: 0 / 0
TEncoding и его потомки
    #39531811
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
white_niggerMaxByteSequenceLen = 6; // max bytes per character
Которая, если верить рефлектору, нигде не используется :)
...
Рейтинг: 0 / 0
TEncoding и его потомки
    #39531818
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Kazantsev Alexey...если верить рефлектору
Хотя, это же константа...
...
Рейтинг: 0 / 0
TEncoding и его потомки
    #39531824
white_nigger
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Kazantsev AlexeyКоторая, если верить рефлектору, нигде не используется :)Фи.. рефлектор.. Проще в репозитории, в сырцах глянуть. Там используется в паре мест в методе ReadData
...
Рейтинг: 0 / 0
TEncoding и его потомки
    #39531825
white_nigger
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Короче предлагаю оставить это на их совести и продолжать с этим жить
...
Рейтинг: 0 / 0
22 сообщений из 22, страница 1 из 1
Форумы / Delphi [игнор отключен] [закрыт для гостей] / TEncoding и его потомки
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]