Как получить согласованное байтовое представление строк в C # без указания кодировки вручную?

Функция

в основном set.seed () поможет повторно использовать один и тот же набор случайных величин, которые нам понадобятся в будущем, чтобы снова оценить конкретную задачу снова с помощью тех же случайных varibales

, нам просто нужно объявить это перед использованием любой функции генерации случайных чисел.

2088
задан Dragonthoughts 1 October 2018 в 12:36
поделиться

12 ответов

byte[] strToByteArray(string str)
{
    System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
    return enc.GetBytes(str);
}
16
ответ дан gkrogers 1 October 2018 в 12:36
поделиться

Ключевой вопрос - то, что глиф в строке берет 32 бита (16 битов для кода символа), но байт только имеет 8 битов для экономии. Непосредственное отображение не существует, если Вы не ограничиваете себя строками, которые только содержат символы ASCII. Система. Текст. Кодирование имеет много способов отобразить строку на байт [], необходимо выбрать тот, который избегает потери информации, и это просто в использовании клиентом, когда она должна отобразить байт [] назад к строке.

Utf8 является популярным кодированием, это компактно и не с потерями.

11
ответ дан Hans Passant 1 October 2018 в 12:36
поделиться

Это зависит от кодирования Вашей строки ( 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 UTF-16 для представления строк, поэтому если Вы просто хотите получить точные байты, которые использует.NET, используйте System.Text.Encoding.Unicode.GetBytes (...).

См. Кодировка символов в Платформе.NET (MSDN) для получения дополнительной информации.

1087
ответ дан Peter Mortensen 1 October 2018 в 12:36
поделиться
  • 1
    Параметр настройки отладки был тем, что я должен был сделать. Я пробовал к resymbolicate, но в выпуске отладочные символы разделяются так symbolication, не возможно. Это с моими настройками выпуска (которые являются более или менее значением по умолчанию, единственным хорошим ответом. Спасибо! – doozMen 12 April 2013 в 13:53

Я не уверен, но я думаю, что строка хранит свою информацию как массив Символов, который неэффективен с байтами. А именно, определение Символа, "Представляет символ Unicode".

берут этот образец в качестве примера:

String str = "asdf éß";
String str2 = "asdf gh";
EncodingInfo[] info =  Encoding.GetEncodings();
foreach (EncodingInfo enc in info)
{
    System.Console.WriteLine(enc.Name + " - " 
      + enc.GetEncoding().GetByteCount(str)
      + enc.GetEncoding().GetByteCount(str2));
}

Обращают внимание, что ответ Unicode составляет 14 байтов в обоих экземплярах, тогда как ответ UTF-8 составляет только 9 байтов для первого, и только 7 для второго.

Поэтому, если Вы просто хотите байты, используемые строкой, просто используйте Encoding.Unicode, но это будет неэффективно с пространством памяти.

13
ответ дан iliketocode 1 October 2018 в 12:36
поделиться
  • 1
    Мой двоичный файл isn' t перечисленный в списке (согласно 2.) Кто-либо еще встретился с этой проблемой и нашел решение? – Clafou 8 October 2012 в 13:52

Необходимо принять кодирование во внимание, потому что 1 символ мог быть представлен 1 или более байты (до приблизительно 6), и различная кодировка будет рассматривать эти байты по-другому.

у Joel есть регистрация на этом:

Абсолютный минимум Каждый Разработчик программного обеспечения Absolutely, Положительно Должен Знать О Unicode и Наборах символов (Никакие Оправдания!)

91
ответ дан Zhaph - Ben Duguid 1 October 2018 в 12:36
поделиться
  • 1
    Профилирование производительности в Выпуске дает очень different— и больше useful— результаты, чем в Отладке. Переключение установки Profile для Отладки не является хорошей идеей. – OldPeculier 23 April 2012 в 18:32
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());
110
ответ дан Michael Buen 1 October 2018 в 12:36
поделиться
  • 1
    + 180 Это должно быть отмеченным как корректный ответ. – jdog 27 September 2012 в 01:07

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

я обращусь к Вашему последующему вопросу: почему необходимо выбрать кодирование? Почему Вы не можете получить это от самого строкового класса?

ответ находится в двух частях.

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

, Если Ваша программа полностью в.Net мире тогда, Вы не должны волноваться о получении массивов байтов для строк вообще даже при отправке данных через сеть. Вместо этого используйте.Net Сериализацию для волнения о передаче данных. Вы больше не волнуетесь о фактических байтах: средство форматирования Сериализации делает это для Вас.

, С другой стороны, что, если Вы отправляете эти байты куда-нибудь, что Вы не можете гарантировать, вытянет в данных из.Net сериализованного потока? В этом случае определенно необходимо волноваться о кодировании, потому что, очевидно, эта внешняя система заботится. Таким образом, снова внутренние байты, используемые строкой, не имеют значения: необходимо выбрать кодирование, таким образом, можно быть явными об этом кодировании на принимающем конце, даже если это - то же кодирование, используемое внутренне.Net.

я понимаю, что в этом случае Вы могли бы предпочесть использовать фактические байты, сохраненные строковой переменной в памяти, если это возможно, с идеей, что это могло бы сохранить некоторую работу, создающую Ваш поток байтов. Однако я поместил его в Вас, это просто не важно по сравнению с проверкой, что Ваш вывод понят с другой стороны, и гарантировать, что Вы должны быть явными с Вашим кодированием. Кроме того, если Вы действительно хотите соответствовать своим внутренним байтам, можно уже просто выбрать Unicode кодирование и получить ту производительность сбережения.

, Который приносит мне к второй части... выбирающей Unicode, кодирование сообщение.Net для использования базовых байтов. Действительно необходимо выбрать это кодирование, потому что, когда некоторый новомодный Unicode - Плюс выходит.Net время выполнения должно быть свободно использовать эту более новую, лучшую модель кодирования, не повреждая программу. Но, в настоящий момент (и обозримое будущее), просто выбрав кодирование Unicode дает Вам, что Вы хотите.

также важно понять, что Ваша строка должна быть переписана для проводного соединения, и это включает, по крайней мере, некоторый перевод комбинации двоичных разрядов , даже когда Вы используете соответствие, кодирующее . Компьютер должен составлять вещи как Большой по сравнению с Прямым порядком байтов, сетевым порядком байтов, пакетированием, информацией о сессии, и т.д.

43
ответ дан Joel Coehoorn 1 October 2018 в 12:36
поделиться
  • 1
    +1000... Центр внимания никогда не работает правильно с Xcode4 для меня (слишком много ошибок в Центре внимания), и I' ve никогда не находил эффективное обходное решение. You' ve сохранил меня много боли!... PS: XCode должен вывести зависимость Центра внимания; центр внимания является ужасным решением для индексации, и XCode имеет особые потребности - он shouldn' t полагаются на " unreliable" индексатор! – Adam 13 September 2012 в 11:54

Два пути:

public static byte[] StrToByteArray(this string s)
{
    List<byte> value = new List<byte>();
    foreach (char c in s.ToCharArray())
        value.Add(c.ToByte());
    return value.ToArray();
}

И,

public static byte[] StrToByteArray(this string s)
{
    s = s.Replace(" ", string.Empty);
    byte[] buffer = new byte[s.Length / 2];
    for (int i = 0; i < s.Length; i += 2)
        buffer[i / 2] = (byte)Convert.ToByte(s.Substring(i, 2), 16);
    return buffer;
}

я склонен использовать нижнюю часть еще один часто, чем вершина, не сравнили их для скорости.

2
ответ дан 1 October 2018 в 22:36
поделиться
  • 1
    стоп, охладитесь! я почти хочу использовать это, хотя it' ll быть раздражающим для будущей совместимости. – solvingPuzzles 18 September 2012 в 16:00

Также, пожалуйста, объясните, почему следует учитывать кодировку. Разве я не могу просто узнать, в каких байтах была сохранена строка? Почему эта зависимость от кодировки? !!!

Потому что не существует такого понятия, как «байты строки».

Строка (или, в более общем смысле, текст) состоит из символов: букв, цифр и другие символы. Вот и все. Однако компьютеры ничего не знают о персонажах; они могут обрабатывать только байты. Следовательно, если вы хотите сохранить или передать текст с помощью компьютера, вам необходимо преобразовать символы в байты. Как ты это делаешь? Здесь на сцену выходят кодировки.

Кодирование - это не что иное, как соглашение о переводе логических символов в физические байты. Самая простая и известная кодировка - это ASCII, и это все, что вам нужно, если вы пишете на английском языке. Для других языков вам потребуются более полные кодировки, поскольку любой из вариантов Unicode является самым безопасным выбором в настоящее время.

Короче говоря, попытка " так же невозможно, как «написать текст без использования какого-либо языка».

Между прочим, я настоятельно рекомендую вам (и всем в этом отношении) прочитать этот небольшой мудрость: Абсолютный минимум для каждого разработчика программного обеспечения Абсолютно необходимо знать о Unicode и наборах символов (без оправданий!)

23
ответ дан 22 November 2019 в 19:59
поделиться

Самый быстрый способ

public static byte[] GetBytes(string text)
{
    return System.Text.ASCIIEncoding.UTF8.GetBytes(text);
}

ИЗМЕНИТЬ , как прокомментировал Макотосан, теперь это лучший способ:

Encoding.UTF8.GetBytes(text)
8
ответ дан 22 November 2019 в 19:59
поделиться
// C# to convert a string to a byte array.
public static byte[] StrToByteArray(string str)
{
    System.Text.ASCIIEncoding  encoding=new System.Text.ASCIIEncoding();
    return encoding.GetBytes(str);
}


// C# to convert a byte array to a string.
byte [] dBytes = ...
string str;
System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
str = enc.GetString(dBytes);
-1
ответ дан 22 November 2019 в 19:59
поделиться

На то, чтобы быть спрошенным, что Вы намереваетесь сделать с байтами, Вы ответили :

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

Независимо от того, намереваетесь ли Вы отправить этому зашифрованные данные по сети, загрузите ее назад в память позже или парьте ее к другому процессу, Вы ясно предназначаете к , дешифруют это в какой-то момент. В этом случае ответ - то, что Вы определяете протокол связи. Протокол связи не должен быть , определил с точки зрения деталей реализации Вашего языка программирования и его связанного времени выполнения. Существует несколько причин этого:

  • Вы, возможно, должны общаться с процессом, реализованным на другом языке или времени выполнения. (Это могло бы включать сервер, работающий на другой машине или отправляющий строку клиенту браузера JavaScript, например.)
  • программа может быть повторно реализована на другом языке или времени выполнения в будущем.
  • реализация.NET могла бы изменить внутреннее представление строк. Можно думать, что это звучит неправдоподобным, но это на самом деле, оказалось, в Java 9 уменьшало использование памяти. Нет никакой причины.NET не могла следовать примеру. Стрельба по тарелочкам предлагает , что UTF-16, вероятно, не оптимален, сегодня дают повышение эмодзи и другие блоки Unicode, нуждающегося больше чем в 2 байтах для представления также, увеличивая вероятность, что внутреннее представление могло измениться в будущем.

Для передачи (или с абсолютно разрозненным процессом или с той же программой в будущем), необходимо определить протокол строго для уменьшения трудности работы с ним или случайно создания ошибок. В зависимости от внутреннего представления.NET не строгое, ясное, или даже гарантируемый быть последовательным определением. Стандарт, кодирующий , строгое определение, которое не приведет Вас к сбою в будущем.

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

Вы май , конечно принимает решение использовать UTF-16 непосредственно, если Вы находите, что Ваш процесс работает значительно лучше, так как.NET использует его внутренне или по любой другой причине, но необходимо выбрать то кодирование явно и выполнить те преобразования явно в коде, а не в зависимости от внутренней реализации.NET.

Так выбирают кодирование и используют его:

using System.Text;

// ...

Encoding.Unicode.GetBytes("abc"); # UTF-16 little endian
Encoding.UTF8.GetBytes("abc")

, Как Вы видите, это - также на самом деле меньше кода, чтобы просто использовать созданный в кодировании объектов, чем реализовать Ваши собственные методы читателя/устройства записи.

1
ответ дан 22 November 2019 в 19:59
поделиться
Другие вопросы по тегам:

Похожие вопросы: