Питання Як отримати послідовне відображення байтів рядків у C # без вказівки кодування вручну?


Як перетворити a string до a byte[] в .NET (C #) без введення вручну конкретного кодування?

Я збираюся шифрувати рядок. Я можу зашифрувати його без перетворення, але я все ж таки хотів би знати, чому кодування тут гратиме.

Крім того, чому слід враховувати кодування? Чи не можу я просто отримати те, що байтів рядок було збережено? Чому існує залежність від кодування символів?


1911
2018-01-23 13:39


походження


Кожен рядок зберігається як масив байтів правильно? Чому я не можу просто мати ці байти? - Agnel Kurian
Кодування є які символи в байтах. Наприклад, в ASCII буква 'A' відображає цифру 65. В іншому кодуванні вона може бути не однаковою. Підхід високого рівня до рядків, прийнятих у .NET, робить це в значній мірі несуттєвим, хоча (за винятком цього випадку). - Lucas Jones
Щоб грати адвоката диявола: Якщо ви хочете отримати байти в рядку в пам'яті (як .NET використовує їх) і якимось чином керувати ними (тобто CRC32), і НІКОЛИ ніколи не хотів би його декодувати назад у вихідний рядок ... це це не прямо вперед, чому ви турбуєтеся про кодування або як ви вибираєте, який з них використовувати. - Greg
Здивований ніхто не дав цю посилання ще: joelonsoftware.com/articles/Unicode.html - Bevan
Характер не байт, а байт - не символ. Шар - це як ключ до таблиці шрифтів і лексична традиція. Строка - це послідовність символів. (Слова, абзаци, речення та назви мають також свої лексичні традиції, які виправдовують власні визначення типу - але я відволікаюсь). Як цілі числа, числа з плаваючою точкою, і все інше, символи кодуються в байти. Був час, коли кодування було простим один до одного: ASCII. Однак, щоб врахувати всі символи людини, 256 перестановок байтів були недостатніми, а кодування були розроблені для вибіркового використання більшої кількості байтів. - George


Відповіді:


На відміну від відповідей тут, вам не потрібно турбуватися про кодування якщо байти не потрібно інтерпретувати!

Як ви згадали, ваша мета - це просто "отримати що байт рядок зберігається в".
(І, звичайно, щоб мати можливість перебудувати рядок з байтів.)

Для цих цілей я чесно роблюсь ні зрозумійте, чому люди продовжують казати вам, що вам потрібні кодування. Вам, звичайно, НЕ потрібно турбуватися про кодування для цього.

Просто робіть це замість:

static byte[] GetBytes(string str)
{
    byte[] bytes = new byte[str.Length * sizeof(char)];
    System.Buffer.BlockCopy(str.ToCharArray(), 0, bytes, 0, bytes.Length);
    return bytes;
}

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);
}

Поки ваша програма (або інші програми) не намагається тлумачити Якісь байти, про які ви, очевидно, не згадували про те, що маєте намір зробити, то є нічого неправильно з цим підходом! Турбота про кодування просто робить ваше життя складнішим без реальної причини.

Додаткова користь для цього підходу:

Неважливо, якщо рядок містить недійсні символи, тому що ви все одно можете отримати дані та реконструювати початковий рядок в будь-якому випадку!

Вона буде закодована і декодована однаково, тому що ви є просто дивитись на байти.

Однак, якщо ви використовували певне кодування, це дало б вам змогу кодувати / дешифрувати недійсні символи.


1718
2018-04-30 07:44



Що ж потворне про це, це GetString і GetBytes потрібно виконати на системі з тим самим endianness для роботи. Таким чином, ви не можете використовувати це, щоб отримати байти, які ви хочете перетворити на рядок в іншому місці. Тому мені важко придумати ситуації, в яких я хотів би використати це. - CodesInChaos
@CodeInChaos: Як я вже сказав, уся справа в цьому полягає в тому, якщо ви хочете використовувати його в тому ж роді системи з таким самим набором функцій. Якщо ні, то ви не повинні використовувати його. - Mehrdad
-1 Я гарантую, що хтось (хто не розуміє байтів і символів) збирається перетворити їхній рядок в масив байтів, вони будуть генерувати його і читати цю відповідь, і вони будуть робити неправильну річ, тому що майже у всіх випадків кодування IS релевантний - artbristol
@artmbrstol: Якщо їм не треба хвилюватися читати відповідь (або інші відповіді ...), то я шкодую, тоді мені не буде кращого спілкування з ними. Я, як правило, вирішую відповісти на ОП, а не намагатися вгадати, що інші можуть зробити з моєю відповіддю - ОП має право знати, і просто тому, що хтось може зловживати ножем, не означає, що ми повинні приховати всі ножі у світі для себе. Хоча, якщо ви не погоджуєтеся, це теж добре. - Mehrdad
Ця відповідь не так на багатьох рівнях, але, головне, через відмову "вам не потрібно турбуватися про кодування!". 2 методи, GetBytes і GetString є зайвими, оскільки вони є просто повторними реалізаціями того, що вже виконують Encoding.Unicode.GetBytes () і Encoding.Unicode.GetString (). Заява "Доки ваша програма (або інші програми) не намагається інтерпретувати байти" також є принципово недосконалою, оскільки неявно вони означають, що байти слід інтерпретувати як Unicode. - David


Це залежить від кодування вашого рядка (ASCII, UTF-8, ...)

Наприклад:

byte[] b1 = System.Text.Encoding.UTF8.GetBytes (myString);
byte[] b2 = System.Text.Encoding.ASCII.GetBytes (myString);

Невеликий приклад, чому важливо кодування:

string pi = "\u03a0";
byte[] ascii = System.Text.Encoding.ASCII.GetBytes (pi);
byte[] utf8 = System.Text.Encoding.UTF8.GetBytes (pi);

Console.WriteLine (ascii.Length); //Will print 1
Console.WriteLine (utf8.Length); //Will print 2
Console.WriteLine (System.Text.Encoding.ASCII.GetString (ascii)); //Will print '?'

ASCII просто не обладнаний для роботи з особливими символами.

Внутрішньо використовується .NET Framework UTF-16 для представлення рядків, тому, якщо ви просто хочете отримати точні байти, що .NET використовує, використовуйте System.Text.Encoding.Unicode.GetBytes (...).

Побачити Кодування символів у .NET Framework (MSDN) для отримання додаткової інформації.


1052
2018-01-23 13:43



Але, чому кодування потрібно враховувати? Чому я не можу просто отримати байти, не маючи необхідності бачити кодування, яке використовується? Навіть якщо це було потрібно, сам String не повинен знати, що таке кодування, і просто скинути те, що знаходиться в пам'яті? - Agnel Kurian
Струми .NET завжди кодуються як Unicode. Тому використовуйте System.Text.Encoding.Unicode.GetBytes (); щоб отримати набір байтів, який .NET використовуватиме, щоб представляти символи. Однак чому ти хочеш це? Я рекомендую UTF-8, особливо коли більшість персонажів розташовуються в західній латині. - AnthonyWJones
Також: точні байти використовуються всередині рядка не має значення якщо система, яка їх витягує, не обробляє цю кодування або не обробляє її як неправильне кодування. Якщо все в межах. Net, то чому конвертувати до масиву байтів взагалі. В іншому випадку краще бути явним з вашим кодуванням - Joel Coehoorn
@Joel, Будьте обережні з System.Text.Encoding.Default, оскільки він може бути різним на кожній машині, яку він запускає. Ось чому рекомендується завжди вказати кодування, таке як UTF-8. - Ash
Вам не потрібні кодування, якщо ви (чи хтось інший) фактично не плануєте тлумачити дані, замість того, щоб розглядати його як загальний "блок байтів". Для таких речей, як стискання, шифрування тощо, турбота про кодування не має сенсу. Побачити моя відповідь для способу це зробити, не турбуючись про кодування. (Я міг би дати -1 для того, щоб сказати, що вам потрібно турбуватися про кодування, коли ви цього не робите, але сьогодні я особливо не маю на увазі: P) - Mehrdad


Прийнята відповідь дуже, дуже складна. Використовуйте включені класи .NET для цього:

const string data = "A string with international characters: Norwegian: ÆØÅæøå, Chinese: 喂 谢谢";
var bytes = System.Text.Encoding.UTF8.GetBytes(data);
var decoded = System.Text.Encoding.UTF8.GetString(bytes);

Не створюйте колесо, якщо вам не потрібно ...


245
2018-04-30 07:26



Прийнята відповідь не тільки дуже складна, але і рецепт катастрофи. - Konamiman
У випадку, якщо прийнята відповідь змінюється, для цілей запису це саме відповідь Мехрдада на поточний час і дату. Сподіваємось, ОП повернеться до цього і приймемо краще рішення. - Thomas Eding
добре в принципі, але кодування повинно бути System.Text.Encoding.Unicode щоб бути еквівалентом відповіді Мехрдада. - Jodrell
Питання було відредаговано з моменту первинної відповіді, але, можливо, моя відповідь трохи застаріла. Я ніколи не мав наміру надати екстрасенсу еквіваленту відповіді Мехрдада, але даю розумний спосіб це зробити. Але, можливо, ви маєте рацію. Проте фраза "отримати те, що байт зберігається в рядку" в оригінальному питанні дуже неточна. Збережено, де? В пам'ять? На диску? Якщо в пам'яті System.Text.Encoding.Unicode.GetBytes швидше за все, буде точніше. - Erik A. Brandstadmoen
@AMissico ваша пропозиція є помилкою, якщо ви не впевнені, що ваш рядок сумісний з вашою кодуванням за замовчуванням системи (рядок, що містить тільки символи ASCII у вашій системній стандартній кодифікації за замовчуванням). Але ніде не ОП стверджує це. - Frédéric


BinaryFormatter bf = new BinaryFormatter();
byte[] bytes;
MemoryStream ms = new MemoryStream();

string orig = "喂 Hello 谢谢 Thank You";
bf.Serialize(ms, orig);
ms.Seek(0, 0);
bytes = ms.ToArray();

MessageBox.Show("Original bytes Length: " + bytes.Length.ToString());

MessageBox.Show("Original string Length: " + orig.Length.ToString());

for (int i = 0; i < bytes.Length; ++i) bytes[i] ^= 168; // pseudo encrypt
for (int i = 0; i < bytes.Length; ++i) bytes[i] ^= 168; // pseudo decrypt

BinaryFormatter bfx = new BinaryFormatter();
MemoryStream msx = new MemoryStream();            
msx.Write(bytes, 0, bytes.Length);
msx.Seek(0, 0);
string sx = (string)bfx.Deserialize(msx);

MessageBox.Show("Still intact :" + sx);

MessageBox.Show("Deserialize string Length(still intact): " 
    + sx.Length.ToString());

BinaryFormatter bfy = new BinaryFormatter();
MemoryStream msy = new MemoryStream();
bfy.Serialize(msy, sx);
msy.Seek(0, 0);
byte[] bytesy = msy.ToArray();

MessageBox.Show("Deserialize bytes Length(still intact): " 
   + bytesy.Length.ToString());

105
2018-01-23 16:36



Ви можете використовувати один і той же екземпляр BinaryFormatter для всіх цих операцій - Joel Coehoorn
Дуже цікаво. Очевидно, що буде випадати будь-який високий сурогатний Unicode-символ. Дивіться документацію на [BinaryFormatter] - John Robertson
@ ErikA.Brandstadmoen Подивіться мої тести тут: stackoverflow.com/a/10384024 - Michael Buen


Вам необхідно взяти кодування в обліковий запис, оскільки 1 символ може бути представлений 1 або більш байтів (до приблизно 6), і різні кодування будуть обробляти ці байти по-різному.

Джоел має повідомлення про це:

Абсолютний мінімум кожен розробник програм абсолютно, позитивно повинен знати про Unicode і набори символів (без виправлень!)


79
2018-01-23 14:03



"1 символ може бути представлений 1 або більше байтів" Я згоден. Я просто хочу, щоб ці байти незалежно від того, що кодує рядок. Єдиний спосіб, яким рядок може бути збережений в пам'яті, - це байти. Навіть символи зберігаються як 1 або більше байт. Я просто хочу, щоб мої руки на них байтів. - Agnel Kurian
Вам не потрібні кодування, якщо ви (чи хтось інший) фактично не плануєте тлумачити дані, замість того, щоб розглядати його як загальний "блок байтів". Для таких речей, як стискання, шифрування тощо, турбота про кодування не має сенсу. Побачити моя відповідьдля способу це зробити, не турбуючись про кодування. - Mehrdad
@Mehrdad - Загалом, але оригінальне питання, як було заявлено, коли я відповів, я не бачив, яким ОП станеться з цими байтами, після того, як вони перетворили їх, а для майбутніх шукачів інформація про це є актуальною - це вкритий Відповідь Джоеля досить добре - і як ви стверджуєте в своїй відповіді: за умови, що ви палите в світі. NET, і використовуйте ваші методи перетворення в / з, ви щасливі. Як тільки ви вийдете ззовні, кодування матиме значення. - Zhaph - Ben Duguid


Це популярне запитання. Важливо зрозуміти, про що запитує автор питання, і що він відрізняється від того, що, ймовірно, найбільш поширеною потребою. Щоб запобігти неправильному використанню коду, де воно не потрібне, я відповів на це пізніше.

Загальна потреба

Кожен рядок має набір символів і кодування. Коли ви перетворюєте a System.String об'єкт до масиву System.Byte у вас ще є набір символів і кодування. Для більшості звичаїв, ви б знали, який набір символів і кодування потрібно, і .NET полегшує "копіювання за допомогою конверсії". Просто виберіть відповідний Encoding клас

// using System.Text;
Encoding.UTF8.GetBytes(".NET String to byte array")

Для перетворення може знадобитися розглянути випадки, коли набір набору чи кодування цілі не підтримує символ, який знаходиться в джерелі. Ви маєте вибір: виключення, заміщення чи пропуск. Політика за замовчуванням - замінити "?".

// using System.Text;
var text = Encoding.ASCII.GetString(Encoding.ASCII.GetBytes("You win €100")); 
                                                      // -> "You win ?100"

Зрозуміло, що перетворення не обов'язково без втрат!

Примітка: для System.String набір вихідних кодів є Unicode.

Єдина помилка в тому, що .NET використовує ім'я набору символів для назви одного конкретного кодування цього набору символів. Encoding.Unicode слід назвати Encoding.UTF16.

Це для більшості звичаїв. Якщо вам це потрібно, перестаньте читати тут. Дивіться веселощі Стаття Джоеля Спольського якщо ви не розумієте, що таке кодування.

Особлива потреба

Тепер автор запитує: "Кожен рядок зберігається як масив байтів, чи не так? Чому я не можу просто мати ці байти?"

Він не хоче конверсії.

Від C # spec:

Обробка символів і рядків у C # використовує кодування Unicode. Шар   Тип представляє кодовий блок UTF-16, а тип рядка представляє собою   послідовність кодових одиниць UTF-16.

Отже, ми знаємо, що якщо ми попросимо нульову конверсію (наприклад, з UTF-16 до UTF-16), ми отримаємо бажаний результат:

Encoding.Unicode.GetBytes(".NET String to byte array")

Але щоб уникнути згадування кодувань, ми повинні зробити це іншим способом. Якщо прийнятний тип проміжних даних, для цього є концептуальний ярлик:

".NET String to byte array".ToCharArray()

Це не дає нам бажаного типу даних, але Відповідь Мехрдада показує, як перетворити цей масив масиву в масив байтів за допомогою BlockCopy. Однак, це копіює рядок двічі! І це також явно використовує кодування-специфічний код: тип даних System.Char.

Єдиний спосіб дістатись до фактичних байтів, який String зберігає, - це використання покажчика. The fixed Заява дозволяє прийняти адресу значень. З специфікації C #:

[Для] вираження рядка типу, ... ініціалізатор обчислює значення   адреса першого символу в рядку.

Для цього компілятор записує код, пропускаючи інші частини рядкового об'єкта з RuntimeHelpers.OffsetToStringData. Отже, щоб отримати сирі байти, просто створіть вказівник на рядок і скопіюйте необхідну кількість байтів.

// using System.Runtime.InteropServices
unsafe byte[] GetRawBytes(String s)
{
    if (s == null) return null;
    var codeunitCount = s.Length;
    /* We know that String is a sequence of UTF-16 codeunits 
       and such codeunits are 2 bytes */
    var byteCount = codeunitCount * 2; 
    var bytes = new byte[byteCount];
    fixed(void* pRaw = s)
    {
        Marshal.Copy((IntPtr)pRaw, bytes, 0, byteCount);
    }
    return bytes;
}

Як зазначив @CodesInChaos, результат залежить від кінцевої кількості машини. Але питання автора це не стосується.


76
2017-12-02 04:43



Загалом, не правильно встановити byteCount до подвійної довжини струни. Для кодів Unicode за межами Базової багатомовної літаки для кожного символу буде два 16-бітних кодів. - Jan Hettich
@Jan Це правильно, але довжина рядка вже дає кількість кодових одиниць (не кодових точок). - Tom Blodget
Дякуємо, що вказали на це! З MSDN: "The Length власність [of String] повертає число Char об'єкти у даному випадку, а не кількість символів Unicode ". Тому ваш приклад коду правильний, як написано. - Jan Hettich
@TomBlodget: Цікаво, якщо взяти екземпляри Globalization.SortKey, витягує KeyData, і упаковує результуючі байти з кожного в a String [два байти на символ Спочатку MSB], дзвонив String.CompareOrdinal на результуючі рядки буде значно швидше, ніж дзвонити SortKey.Compare на примірниках SortKey, або навіть дзвінок memcmp на цих випадках. Враховуючи це, мені цікаво, чому KeyData повертає a Byte[] а не а String? - supercat
@TomBlodget: вам не потрібно fixed або unsafe код, ви також можете зробити var gch = GCHandle.Alloc("foo", GCHandleType.Pinned); var arr = new byte[sizeof(char) * ((string)gch.Target).Length]; Marshal.Copy(gch.AddrOfPinnedObject(), arr, 0, arr.Length); gch.Free(); - Mehrdad


Просто продемонструвати звучання Меддрада відповісти працює, його підхід може навіть зберегти непарних сурогатних персонажів(багато з яких були висунуті проти моєї відповіді, однак про це всі однаково винні, наприклад System.Text.Encoding.UTF8.GetBytes, System.Text.Encoding.Unicode.GetBytes; ці методи кодування не можуть зберігати високі сурогатні символи d800наприклад, і просто просто заміняють високі сурогатні символи з значенням fffd ):

using System;

class Program
{     
    static void Main(string[] args)
    {
        string t = "爱虫";            
        string s = "Test\ud800Test"; 

        byte[] dumpToBytes = GetBytes(s);
        string getItBack = GetString(dumpToBytes);

        foreach (char item in getItBack)
        {
            Console.WriteLine("{0} {1}", item, ((ushort)item).ToString("x"));
        }    
    }

    static byte[] GetBytes(string str)
    {
        byte[] bytes = new byte[str.Length * sizeof(char)];
        System.Buffer.BlockCopy(str.ToCharArray(), 0, bytes, 0, bytes.Length);
        return bytes;
    }

    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);
    }        
}

Вихід:

T 54
e 65
s 73
t 74
? d800
T 54
e 65
s 73
t 74

Спробуйте це з System.Text.Encoding.UTF8.GetBytes або System.Text.Encoding.Unicode.GetBytes, вони просто замінять високі сурогатні символи цінністю фффд

Щоразу, коли в цьому питанні відбувається рух, я все ще думаю про серіалізатор (будь то від Microsoft або від стороннього компонента), який може зберігати рядки, навіть містить непарні сурогатні символи; Я це зараз гумаюю: серіалізація непарного сурогатного персонажа .NET. Це не змусить мене втрачати сон, але це нагадує, коли кожен раз, коли хтось коментує мою відповідь, що це недоліки, однак їх відповіді є рівноправними, коли справа доходить до непарних сурогатних персонажів.

Тінь, що Microsoft мав щойно використати System.Buffer.BlockCopy в його BinaryFormatter ツ

谢谢!


35
2017-07-25 22:52



Чи не повинні сурогати з'являтися парами, щоб створити дійсні кодові точки? Якщо це так, я можу зрозуміти, чому дані будуть викрадені. - dtanders
@dtanders Так, це теж мої думки, вони повинні з'являтися попарно, непарні сурогатні персонажі просто трапляються, якщо ви навмисно поміщаєте їх в рядок і роблять їх непарними. Те, що я не знаю, - чому інші девелопери продовжують нахабуватись, що замість того, щоб вважати підхід до серіалізації, ми повинні використовувати підхід для кодування.моя відповідь, яка була прийнятою відповіддю більше 3 років) не зберігає непарного сурогатного характеру недоторканими. Але вони забули перевірити, що рішення, що їх кодують, не зберігають також непарного сурогатного персонажа, іронії ツ - Michael Buen
Якщо є бібліотека серіалізації, яка використовує System.Buffer.BlockCopy Внутрішньо, всі аргументи кодування-адвокації людей будуть суперечливими - Michael Buen
Проблема з вашим тестом полягає в тому, що ви зробили недійсний рядок. "У UTF-16 вони завжди повинні з'являтися у парах, як високий сурогат, за яким слідує низький сурогат, таким чином використовуючи 32 біти, щоб позначити одну кодову точку".. Якщо ви дотримуєтесь / uD800 з / uDC00, то він добре працює у всіх форматах Unicode. Важливо відзначити, що це рядки, а не масив масиву, тому певні обмеження мають сенс. Крім того, він працює чудово навіть без / uDC00 в UTF7. - Trisped
@ dtanders: A System.String є незмінною послідовністю Char; .NET завжди дозволив String об'єкт, який буде побудований з будь-якого Char[] і експортувати його вміст в a Char[] що містять однакові значення, навіть якщо оригінал Char[] містить непарні сурогати. - supercat


Спробуйте це, набагато менше коду:

System.Text.Encoding.UTF8.GetBytes("TEST String");

34
2018-01-23 15:54



Потім спробуйте це System.Text.Encoding.UTF8.GetBytes("Árvíztűrő tükörfúrógép);і плач! Це буде працювати, але System.Text.Encoding.UTF8.GetBytes("Árvíztűrő tükörfúrógép").Length != System.Text.Encoding.UTF8.GetBytes("Arvizturo tukorfurogep").Length поки "Árvíztűrő tükörfúrógép".Length == "Arvizturo tukorfurogep".Length - mg30rg
@ mg30rg: Чому ви вважаєте, що ваш приклад є дивним? Звичайно, у кодуванні змінної ширини не всі символи мають однакові двійки байтів. Що з цим не так? - Vlad


Перша частина вашого запитання (як отримати байти) вже відповіла іншими: дивіться в System.Text.Encoding простір імен

Я звертаюсь до наступного запитання: чому вам потрібно вибрати кодування? Чому ти не можеш отримати це з самих рядків класу?

Відповідь складається з двох частин.

Перш за все, байти використовуються всередині класу рядків не має значення, і кожного разу, коли ви припускаєте, що вони роблять, ви, ймовірно, вводите помилку.

Якщо ваша програма повністю перебуває в .Net-світі, то вам не потрібно турбуватися про те, щоб отримувати масиви байтів для рядків взагалі, навіть якщо ви надсилаєте дані через мережу. Замість цього використовуйте .Net Serialization, щоб хвилюватися про передачу даних. Ви більше не хвилюєтеся про фактичні байти: форматування серіалізації робить це для вас.

З іншого боку, що, якщо ви посилаєте ці байти де-небудь, що ви не можете гарантувати, витягне дані з серійного потоку .Net? У цьому випадку вам обов'язково потрібно турбуватися про кодування, оскільки, очевидно, ця зовнішня система зацікавлена. Отже, внутрішні байти, що використовуються ланцюжком, не мають значення: потрібно вибрати кодування, щоб ви могли бути явними про це кодування на приймальному кінці, навіть якщо це те саме кодування, що використовується всередині .Net.

Я розумію, що в цьому випадку ви можете скористатися фактичними байтами, збереженими за допомогою рядкової змінної в пам'яті, де це можливо, з ідеєю, що вона може зберегти певну роботу, створюючи ваш потік байтів. Тим не менш, я поставив це вам не дуже важливо, порівняно з тим, щоб переконатися, що ваш вихід розуміється на іншому кінці, і гарантувати, що ви повинен Будьте явними з вашим кодуванням. Крім того, якщо ви дійсно хочете зіставити свої внутрішні байти, ви вже можете просто вибрати Unicode кодування та отримати таку економію.

Котрий приносить мені до другої частини ... збираючи Unicode кодування є Говорити. Net використовувати базові байти. Вам потрібно вибрати це кодування, тому що коли з'являється якийсь новий Unicode-Plus, час роботи .Net має бути вільний використати цю нову, кращу модель кодування, не порушуючи вашу програму. Але, на даний момент (і в найближчому майбутньому), просто вибір кодування Unicode дає вам те, що ви хочете.

Важливо також зрозуміти, що ваш рядок повинен бути переписаний на дріт, і це передбачає принаймні деякий переклад біт-шаблону навіть коли ви використовуєте відповідну кодування. Комп'ютер потребує обліку таких речей, як Big vs. Little Endian, порядок байтів мережі, пакетування, інформація про сеанс тощо.


34
2018-03-10 08:57



Є області в .NET, де вам доведеться отримати байтові масиви для рядків. Багато хто з класів. NET Cryptrography містять такі методи, як ComputeHash (), які приймають масив байтів або потік. У вас немає альтернативи, крім першого перетворення рядка в масив байтів (вибравши Кодування), а потім необов'язково загорнути його в потік. Однак, поки ви виберете кодування (тобто UTF8) палицю з нею, немає проблем з цим. - Ash