@SergeySerge11

Почему не работает System.Text.Encoding? Ошибается на 1 символ?

В чем ошибка. Почти всегда -3 short (или 65000+ ) значение в декодировании из массива в строку?
Вывод:
False i= 2
3 _ 3
30133 -8710 -14349疵�쟳
30133 -3 -14349疵�쟳

//   https://www.onlinegdb.com/online_csharp_compiler
using System;
class HelloWorld
{
  static void Main ()
  { for(int i=0;i<100000;i++){
       string  str= generate();
       byte[]buf= System.Text.Encoding.BigEndianUnicode.GetBytes(str);
       string strPre= System.Text.Encoding.BigEndianUnicode.GetString(buf, 0, buf.Length);
       if(!str.Equals(strPre)){
           Console.WriteLine(str.Equals(strPre) +" i= "+i);
           Console.WriteLine(str.Length+" _ "+strPre.Length);
           for(int l=0;l<str.Length;l++)Console.Write(" "+(short)str[l]);
        Console.WriteLine( str.ToCharArray());
         for(int l=0;l<strPre.Length;l++)Console.Write(" "+(short)strPre[l]);
        Console.WriteLine(strPre.ToCharArray());
        return;
       }
  }
    
  }
     
        static string GetString(byte[] bytes)
        {
            char[] chars = new char[bytes.Length / sizeof(char)];
            System.Buffer.BlockCopy(bytes, 0, chars, 0, bytes.Length);
            return new string(chars);
        }
 
        private static string generate()
        { 
            Random r = new Random();
             
                        byte[] buf = new byte[r.Next(20)*2]; 
                        r.NextBytes(buf);
                        if (buf.Length > 0)
                             return GetString(buf) ;
                        else
                          return "" ; 
        } 
}
  • Вопрос задан
  • 77 просмотров
Пригласить эксперта
Ответы на вопрос 2
twobomb
@twobomb
Ну потому-что ваш генератор тупо генерирует рандомные числа от 0 до FFFF, а в UTF16 там есть определенные правила. Почитайте например в вики

Я не вникал ну вики говорит что там есть диапазон для суррогатных пар тоесть символы которые кодируются двумя 16битными словами, тоесть 4 байтами. Крч как вариант или тупо добавить проверку в генератор чтобы если рандомное число входит в диапазон исключений D80016..DFFF16 то пропускать и генерировать другое. Или замарачиваться с этими парами, ну это будет сложнее.

Принцип кодирования
В UTF-16 символы кодируются двухбайтовыми словами с использованием всех возможных диапазонов значений (от 0 до FFFF16). При этом можно кодировать символы Unicode в диапазонах 000016..D7FF16 и E00016..FFFF16. Исключенный отсюда диапазон D80016..DFFF16 используется как раз для кодирования так называемых суррогатных пар — символов, которые кодируются двумя 16-битными словами.

Символы Unicode до FFFF16 включительно (исключая диапазон для суррогатов) записываются как есть 16-битным словом.

Символы же в диапазоне 1000016..10FFFF16 (больше 16 бит) кодируются по следующей схеме:

Из кода символа вычитается 1000016. В результате получится значение от нуля до FFFFF16, которое помещается в разрядную сетку 20 бит.
Старшие 10 бит (число в диапазоне 000016..03FF16) суммируются с D80016, и результат идёт в ведущее (первое) слово, которое входит в диапазон D80016..DBFF16.
Младшие 10 бит (тоже число в диапазоне 000016..03FF16) суммируются с DC0016, и результат идёт в последующее (второе) слово, которое входит в диапазон DC0016..DFFF16.
Ответ написан
Комментировать
vabka
@vabka Куратор тега C#
Токсичный шарпист
Предположу, что ошибка в том, что Random генерирует невалидные последовательности байтов, которые невозможно интерпретировать как какой-то определённый символ.
Вот от этого и возникает несоответствие.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы