¿Cómo obtengo una representación de bytes consistente en cadenas en C # sin especificar manualmente una encoding?

¿Cómo convierto una string en un byte[] en .NET (C #) sin especificar manualmente una encoding específica?

Voy a cifrar la cadena. Puedo encriptarlo sin convertirlo, pero aún me gustaría saber por qué la encoding viene a jugar aquí.

Además, ¿por qué debería tenerse en cuenta la encoding? ¿No puedo simplemente obtener los bytes en los que se ha almacenado la cadena? ¿Por qué hay una dependencia en las codificaciones de caracteres?

A diferencia de las respuestas aquí, NO es necesario preocuparse por la encoding si no es necesario interpretar los bytes.

Como mencionaste, tu objective es, simplemente, “obtener en qué bytes se ha almacenado la cadena” .
(Y, por supuesto, para poder reconstruir la cadena a partir de los bytes).

Para esos objectives, honestamente no entiendo por qué la gente sigue diciéndote que necesitas las codificaciones. Ciertamente NO necesitas preocuparte por las codificaciones para esto.

Solo haz esto en su lugar:

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

Siempre que su progtwig (u otros progtwigs) no intenten interpretar los bytes de alguna manera, lo que obviamente no mencionó tiene la intención de hacer, ¡entonces no hay nada de malo en este enfoque! Preocuparse por las codificaciones solo hace tu vida más complicada sin una razón real.

Beneficio adicional a este enfoque:

No importa si la cadena contiene caracteres no válidos, porque de todos modos puede obtener los datos y reconstruir la cadena original.

Se codificará y decodificará de la misma manera, porque solo estás mirando los bytes .

Sin embargo, si usaste una encoding específica, te hubiera dado problemas con la encoding / desencoding de caracteres no válidos.

Depende de la encoding de su cadena ( ASCII , UTF-8 , …).

Por ejemplo:

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

Una pequeña muestra por qué la encoding importa:

 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 simplemente no está equipado para tratar con caracteres especiales.

Internamente, .NET Framework usa UTF-16 para representar cadenas, por lo que si simplemente desea obtener los bytes exactos que usa .NET, use System.Text.Encoding.Unicode.GetBytes (...) .

Consulte Codificación de caracteres en .NET Framework (MSDN) para obtener más información.

La respuesta aceptada es muy, muy complicada. Use las clases .NET incluidas para esto:

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

No reinventes la rueda si no tienes que …

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

Debe tener en cuenta la encoding, ya que 1 carácter podría representarse con 1 o más bytes (hasta aproximadamente 6), y diferentes codificaciones tratarán estos bytes de manera diferente.

Joel tiene una publicación sobre esto:

El mínimo absoluto de cada desarrollador de software Absolutamente, definitivamente debe saber sobre Unicode y juegos de caracteres (¡Sin excusas!)

Esta es una pregunta popular. Es importante entender lo que pregunta el autor de la pregunta, y que es diferente de lo que probablemente sea la necesidad más común. Para desalentar el mal uso del código donde no es necesario, primero he respondido el primero.

Necesidad común

Cada cadena tiene un conjunto de caracteres y encoding. Cuando convierte un objeto System.String en una matriz de System.Byte , todavía tiene un juego de caracteres y una encoding. Para la mayoría de los usos, sabrá qué conjunto de caracteres y encoding necesita y .NET simplifica la “copia con conversión”. Simplemente elija la clase de Encoding adecuada.

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

La conversión puede necesitar manejar casos donde el conjunto de caracteres objective o la encoding no admite un carácter que está en la fuente. Usted tiene algunas opciones: excepción, sustitución u omisión. La política predeterminada es sustituir un ‘?’.

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

Claramente, las conversiones no son necesariamente sin pérdidas.

Nota: Para System.String el conjunto de caracteres fuente es Unicode.

Lo único confuso es que .NET usa el nombre de un conjunto de caracteres para el nombre de una encoding particular de ese juego de caracteres. Encoding.Unicode debe llamar Encoding.UTF16 .

Eso es todo para la mayoría de los usos. Si eso es lo que necesitas, deja de leer aquí. Vea el divertido artículo de Joel Spolsky si no entiende qué es una encoding.

Necesidad específica

Ahora, el autor de la pregunta pregunta: “Cada cadena se almacena como una matriz de bytes, ¿verdad? ¿Por qué no puedo simplemente tener esos bytes?”

Él no quiere ninguna conversión.

De la especificación de C # :

El procesamiento de caracteres y cadenas en C # usa encoding Unicode. El tipo de carácter representa una unidad de código UTF-16, y el tipo de cadena representa una secuencia de unidades de código UTF-16.

Entonces, sabemos que si solicitamos la conversión nula (es decir, de UTF-16 a UTF-16), obtendremos el resultado deseado:

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

Pero para evitar la mención de codificaciones, debemos hacerlo de otra manera. Si un tipo de datos intermedio es aceptable, hay un atajo conceptual para esto:

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

Eso no nos da el tipo de datos deseado, pero la respuesta de Mehrdad muestra cómo convertir esta matriz Char a una matriz Byte usando BlockCopy . Sin embargo, ¡esto copia la cadena dos veces! Y, de manera muy explícita, utiliza un código específico de encoding: el tipo de datos System.Char .

La única manera de llegar a los bytes reales en los que se almacena la cadena es usar un puntero. La instrucción fixed permite tomar la dirección de los valores. De la especificación de C #:

[Para] una expresión de tipo cadena, … el inicializador calcula la dirección del primer carácter en la cadena.

Para hacerlo, el comstackdor escribe el código salteado sobre las otras partes del objeto de cadena con RuntimeHelpers.OffsetToStringData . Entonces, para obtener los bytes sin formato, solo cree un puntero a la cadena y copie el número de bytes necesarios.

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

Como señaló @CodesInChaos, el resultado depende de la endianidad de la máquina. Pero al autor de la pregunta no le preocupa eso.

Solo para demostrar que la respuesta de sonido de Mehrdrad funciona, su enfoque puede incluso persistir en los personajes sustitutos no pareados (muchos de los cuales se han nivelado en contra de mi respuesta, pero de los cuales todos son igualmente culpables, por ejemplo, System.Text.Encoding.UTF8.GetBytes , System.Text.Encoding.Unicode.GetBytes ; los métodos de encoding no pueden persistir, por ejemplo, con los caracteres substitutos d800 , y simplemente reemplazan los caracteres sustitutos altos con el valor 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); } } 

Salida:

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

Pruébalo con System.Text.Encoding.UTF8.GetBytes o System.Text.Encoding.Unicode.GetBytes , simplemente reemplazarán los caracteres de sustitución altos con el valor fffd

Cada vez que hay un movimiento en esta pregunta, todavía estoy pensando en un serializador (ya sea de Microsoft o de un componente de terceros) que puede persistir cadenas, incluso si contiene caracteres sustitutos no pareados. Lo googleo de vez en cuando: serialización personaje independiente sin aparear .NET . Esto no me hace perder sueño, pero es algo molesto cuando de vez en cuando hay alguien que comenta mi respuesta que es defectuoso, pero sus respuestas son igualmente erróneas cuando se trata de personajes sustitutos no pareados.

Maldición, Microsoft debería haber usado System.Buffer.BlockCopy en su BinaryFormatter

谢谢!

Prueba esto, mucho menos código:

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

La primera parte de su pregunta (cómo obtener los bytes) ya fue respondida por otros: busque en el System.Text.Encoding nombres System.Text.Encoding .

Dirigiré tu pregunta de seguimiento: ¿por qué necesitas elegir una encoding? ¿Por qué no puedes obtener eso de la clase de cuerdas en sí?

La respuesta está en dos partes.

En primer lugar, los bytes utilizados internamente por la clase de cadena no importan , y cada vez que suponga que lo hacen es probable que introduzca un error.

Si su progtwig está completamente dentro del mundo .Net, entonces no necesita preocuparse por obtener matrices de bytes para cadenas, incluso si está enviando datos a través de una red. En su lugar, utilice Serialización .Net para preocuparse por la transmisión de los datos. Ya no te preocupes por los bytes reales: el formateador de serialización lo hace por ti.

Por otro lado, ¿qué sucede si está enviando estos bytes a alguna parte que no pueda garantizar que obtendrá datos de una transmisión en serie .Net? En este caso, definitivamente debe preocuparse por la encoding, porque obviamente este sistema externo le importa. De nuevo, los bytes internos utilizados por la cadena no importan: debe elegir una encoding para que pueda ser explícito sobre esta encoding en el extremo receptor, incluso si es la misma encoding utilizada internamente por .Net.

Entiendo que, en este caso, es posible que prefiera utilizar los bytes reales almacenados por la variable de cadena en la memoria siempre que sea posible, con la idea de que podría ahorrar algo de trabajo creando su secuencia de bytes. Sin embargo, te lo aseguro, no es importante en comparación con asegurarte de que tu producto se entiende en el otro extremo y garantizar que debes ser explícito con tu encoding. Además, si realmente desea hacer coincidir sus bytes internos, ya puede elegir la encoding Unicode y obtener ese ahorro de rendimiento.

Lo que me lleva a la segunda parte … elegir la encoding Unicode es decirle a .Net que use los bytes subyacentes. Debe elegir esta encoding, porque cuando sale un Unicode-Plus nuevo, el tiempo de ejecución de .Net debe ser libre de usar este modelo de encoding nuevo y mejor sin romper su progtwig. Pero, por el momento (y por un futuro previsible), simplemente elegir la encoding Unicode le da lo que quiere.

También es importante comprender que su cadena debe volver a escribirse en hilo, y eso implica al menos alguna traducción del patrón de bits incluso cuando utiliza una encoding coincidente . La computadora necesita contar cosas como Big vs Little Endian, orden de bytes de red, paquetización, información de sesión, etc.

Bien, he leído todas las respuestas y se trata de usar encoding o una sobre serialización que quita a los sustitutos sin parear.

Es malo cuando la cadena, por ejemplo, proviene de SQL Server, donde se creó a partir de una matriz de bytes almacenada, por ejemplo, un hash de contraseña. Si eliminamos algo de él, almacenará un hash no válido, y si queremos almacenarlo en XML, queremos dejarlo intacto (porque el escritor XML arroja una excepción en cualquier sustituto sin aparear que encuentre).

Así que utilizo la encoding Base64 de matrices de bytes en tales casos, pero bueno, en Internet solo hay una solución para esto en C #, y tiene un error y es de una sola manera, así que he reparado el error y lo escribí de nuevo procedimiento. Aquí está, futuros googlers:

 public static byte[] StringToBytes(string str) { byte[] data = new byte[str.Length * 2]; for (int i = 0; i < str.Length; ++i) { char ch = str[i]; data[i * 2] = (byte)(ch & 0xFF); data[i * 2 + 1] = (byte)((ch & 0xFF00) >> 8); } return data; } public static string StringFromBytes(byte[] arr) { char[] ch = new char[arr.Length / 2]; for (int i = 0; i < ch.Length; ++i) { ch[i] = (char)((int)arr[i * 2] + (((int)arr[i * 2 + 1]) << 8)); } return new String(ch); } 

Además, explique por qué se debe tener en cuenta la encoding. ¿No puedo simplemente obtener los bytes en los que se ha almacenado la cadena? ¿Por qué esta dependencia en la encoding?

Porque no existe tal cosa como “los bytes de la cadena”.

Una cadena (o, más genéricamente, un texto) está compuesta de caracteres: letras, dígitos y otros símbolos. Eso es todo. Las computadoras, sin embargo, no saben nada sobre los personajes; solo pueden manejar bytes. Por lo tanto, si desea almacenar o transmitir texto utilizando una computadora, debe transformar los caracteres en bytes. ¿Cómo haces eso? Aquí es donde entran las codificaciones a la escena.

Una encoding no es más que una convención para traducir caracteres lógicos a bytes físicos. La encoding más simple y mejor conocida es ASCII, y es todo lo que necesitas si escribes en inglés. Para otros idiomas, necesitará codificaciones más completas, ya que cualquiera de los sabores Unicode es la opción más segura hoy en día.

Entonces, en resumen, tratar de “obtener los bytes de una cadena sin usar codificaciones” es tan imposible como “escribir un texto sin usar ningún idioma”.

Por cierto, le recomiendo encarecidamente a usted (y a cualquier persona, para el caso) que lea este pequeño fragmento de sabiduría: el mínimo absoluto que todo desarrollador de software debe saber absolutamente sobre Unicode y conjuntos de caracteres (¡sin excusas!)

C # para convertir una string a una matriz de byte :

 public static byte[] StrToByteArray(string str) { System.Text.UTF8Encoding encoding=new System.Text.UTF8Encoding(); return encoding.GetBytes(str); } 
 byte[] strToByteArray(string str) { System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding(); return enc.GetBytes(str); } 

You can use the following code for conversion between string and byte array.

 string s = "Hello World"; // String to Byte[] byte[] byte1 = System.Text.Encoding.Default.GetBytes(s); // OR byte[] byte2 = System.Text.ASCIIEncoding.Default.GetBytes(s); // Byte[] to string string str = System.Text.Encoding.UTF8.GetString(byte1); 

I’m not sure, but I think the string stores its info as an array of Chars, which is inefficient with bytes. Specifically, the definition of a Char is “Represents a Unicode character”.

take this example sample:

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

Take note that the Unicode answer is 14 bytes in both instances, whereas the UTF-8 answer is only 9 bytes for the first, and only 7 for the second.

So if you just want the bytes used by the string, simply use Encoding.Unicode , but it will be inefficient with storage space.

The key issue is that a glyph in a string takes 32 bits (16 bits for a character code) but a byte only has 8 bits to spare. A one-to-one mapping doesn’t exist unless you restrict yourself to strings that only contain ASCII characters. System.Text.Encoding has lots of ways to map a string to byte[], you need to pick one that avoids loss of information and that is easy to use by your client when she needs to map the byte[] back to a string.

Utf8 is a popular encoding, it is compact and not lossy.

Fastest way

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

EDIT as Makotosan commented this is now the best way:

 Encoding.UTF8.GetBytes(text) 

Utilizar:

  string text = "string"; byte[] array = System.Text.Encoding.UTF8.GetBytes(text); 

El resultado es:

 [0] = 115 [1] = 116 [2] = 114 [3] = 105 [4] = 110 [5] = 103 

You can use following code to convert a string to a byte array in .NET

 string s_unicode = "abcéabc"; byte[] utf8Bytes = System.Text.Encoding.UTF8.GetBytes(s_unicode); 

The closest approach to the OP’s question is Tom Blodget’s, which actually goes into the object and extracts the bytes. I say closest because it depends on implementation of the String Object.

 "Can't I simply get what bytes the string has been stored in?" 

Sure, but that’s where the fundamental error in the question arises. The String is an object which could have an interesting data structure. We already know it does, because it allows unpaird surrogates to be stored. It might store the length. It might keep a pointer to each of the ‘paird’ surrogates allowing quick counting. Etc. All of these extra bytes are not part of the character data.

What you want is each character’s bytes in an array. And that is where ‘encoding’ comes in. By default you will get UTF-16LE. If you don’t care about the bytes themselves except for the round trip then you can choose any encoding including the ‘default’, and convert it back later (assuming the same parameters such as what the default encoding was, code points, bug fixes, things allowed such as unpaird surrogates, etc.

But why leave the ‘encoding’ up to magic? Why not specify the encoding so that you know what bytes you are gonna get?

 "Why is there a dependency on character encodings?" 

Encoding (in this context) simply means the bytes that represent your string. Not the bytes of the string object. You wanted the bytes the string has been stored in — this is where the question was asked naively. You wanted the bytes of string in a contiguous array that represent the string, and not all of the other binary data that a string object may contain.

Which means how a string is stored is irrelevant. You want a string “Encoded” into bytes in a byte array.

I like Tom Bloget’s answer because he took you towards the ‘bytes of the string object’ direction. It’s implementation dependent though, and because he’s peeking at internals it might be difficult to reconstitute a copy of the string.

Mehrdad’s response is wrong because it is misleading at the conceptual level. You still have a list of bytes, encoded. His particular solution allows for unpaird surrogates to be preserved — this is implementation dependent. His particular solution would not produce the string’s bytes accurately if GetBytes returned the string in UTF-8 by default.


I’ve changed my mind about this (Mehrdad’s solution) — this isn’t getting the bytes of the string; rather it is getting the bytes of the character array that was created from the string. Regardless of encoding, the char datatype in c# is a fixed size. This allows a consistent length byte array to be produced, and it allows the character array to be reproduced based on the size of the byte array. So if the encoding were UTF-8, but each char was 6 bytes to accommodate the largest utf8 value, it would still work. So indeed — encoding of the character does not matter.

But a conversion was used — each character was placed into a fixed size box (c#’s character type). However what that representation is does not matter, which is technically the answer to the OP. So — if you are going to convert anyway… Why not ‘encode’?

Here is my unsafe implementation of String to Byte[] conversion:

 public static unsafe Byte[] GetBytes(String s) { Int32 length = s.Length * sizeof(Char); Byte[] bytes = new Byte[length]; fixed (Char* pInput = s) fixed (Byte* pBytes = bytes) { Byte* source = (Byte*)pInput; Byte* destination = pBytes; if (length >= 16) { do { *((Int64*)destination) = *((Int64*)source); *((Int64*)(destination + 8)) = *((Int64*)(source + 8)); source += 16; destination += 16; } while ((length -= 16) >= 16); } if (length > 0) { if ((length & 8) != 0) { *((Int64*)destination) = *((Int64*)source); source += 8; destination += 8; } if ((length & 4) != 0) { *((Int32*)destination) = *((Int32*)source); source += 4; destination += 4; } if ((length & 2) != 0) { *((Int16*)destination) = *((Int16*)source); source += 2; destination += 2; } if ((length & 1) != 0) { ++source; ++destination; destination[0] = source[0]; } } } return bytes; } 

It’s way faster than the accepted anwser’s one, even if not as elegant as it is. Here are my Stopwatch benchmarks over 10000000 iterations:

 [Second String: Length 20] Buffer.BlockCopy: 746ms Unsafe: 557ms [Second String: Length 50] Buffer.BlockCopy: 861ms Unsafe: 753ms [Third String: Length 100] Buffer.BlockCopy: 1250ms Unsafe: 1063ms 

In order to use it, you have to tick “Allow Unsafe Code” in your project build properties. As per .NET Framework 3.5, this method can also be used as String extension:

 public static unsafe class StringExtensions { public static Byte[] ToByteArray(this String s) { // Method Code } } 

Two ways:

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

Y,

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

I tend to use the bottom one more often than the top, haven't benchmarked them for speed.

 bytes[] buffer = UnicodeEncoding.UTF8.GetBytes(string something); //for converting to UTF then get its bytes bytes[] buffer = ASCIIEncoding.ASCII.GetBytes(string something); //for converting to ascii then get its bytes 

simple code with LINQ

 string s = "abc" byte[] b = s.Select(e => (byte)e).ToArray(); 

EDIT : as commented below, it is not a good way.

but you can still use it to understand LINQ with a more appropriate coding :

 string s = "abc" byte[] b = s.Cast().ToArray(); 

Simply use this:

 byte[] myByte= System.Text.ASCIIEncoding.Default.GetBytes(myString); 

With the advent of Span released with C# 7.2, the canonical technique to capture the underlying memory representation of a string into a managed byte array is:

 byte[] bytes = "rubbish_\u9999_string".AsSpan().AsBytes().ToArray(); 

Converting it back should be a non-starter because that means you are in fact interpreting the data somehow, but for the sake of completeness:

 string s; unsafe { fixed (char* f = &bytes.AsSpan().NonPortableCast().DangerousGetPinnableReference()) { s = new string(f); } } 

The names NonPortableCast and DangerousGetPinnableReference should further the argument that you probably shouldn’t be doing this.

Note that working with Span requires installing the System.Memory NuGet package .

Regardless, the actual original question and follow-up comments imply that the underlying memory is not being “interpreted” (which I assume means is not modified or read beyond the need to write it as-is), indicating that some implementation of the Stream class should be used instead of reasoning about the data as strings at all.

If you really want a copy of the underlying bytes of a string, you can use a function like the one that follows. However, you shouldn’t please read on to find out why.

 [DllImport( "msvcrt.dll", EntryPoint = "memcpy", CallingConvention = CallingConvention.Cdecl, SetLastError = false)] private static extern unsafe void* UnsafeMemoryCopy( void* destination, void* source, uint count); public static byte[] GetUnderlyingBytes(string source) { var length = source.Length * sizeof(char); var result = new byte[length]; unsafe { fixed (char* firstSourceChar = source) fixed (byte* firstDestination = result) { var firstSource = (byte*)firstSourceChar; UnsafeMemoryCopy( firstDestination, firstSource, (uint)length); } } return result; } 

This function will get you a copy of the bytes underlying your string, pretty quickly. You’ll get those bytes in whatever way they are encoding on your system. This encoding is almost certainly UTF-16LE but that is an implementation detail you shouldn’t have to care about.

It would be safer, simpler and more reliable to just call,

 System.Text.Encoding.Unicode.GetBytes() 

In all likelihood this will give the same result, is easier to type, and the bytes will always round-trip with a call to

 System.Text.Encoding.Unicode.GetString() 

The string can be converted to byte array in few different ways, due to the following fact: .NET supports Unicode, and Unicode standardizes several difference encodings called UTFs. They have different lengths of byte representation but are equivalent in that sense that when a string is encoded, it can be coded back to the string, but if the string is encoded with one UTF and decoded in the assumption of different UTF if can be screwed up.

Also, .NET supports non-Unicode encodings, but they are not valid in general case (will be valid only if a limited sub-set of Unicode code point is used in an actual string, such as ASCII). Internally, .NET supports UTF-16, but for stream representation, UTF-8 is usually used. It is also a standard-de-facto for Internet.

Not surprisingly, serialization of string into an array of byte and deserialization is supported by the class System.Text.Encoding , which is an abstract class; its derived classes support concrete encodings: ASCIIEncoding and four UTFs ( System.Text.UnicodeEncoding supports UTF-16)

Ref this link.

For serialization to an array of bytes using System.Text.Encoding.GetBytes . For the inverse operation use System.Text.Encoding.GetChars . This function returns an array of characters, so to get a string, use a string constructor System.String(char[]) .
Ref this page.

Ejemplo:

 string myString = //... some string System.Text.Encoding encoding = System.Text.Encoding.UTF8; //or some other, but prefer some UTF is Unicode is used byte[] bytes = encoding.GetBytes(myString); //next lines are written in response to a follow-up questions: myString = new string(encoding.GetChars(bytes)); byte[] bytes = encoding.GetBytes(myString); myString = new string(encoding.GetChars(bytes)); byte[] bytes = encoding.GetBytes(myString); //how many times shall I repeat it to show there is a round-trip? :-) 

From byte[] to string :

  return BitConverter.ToString(bytes); 

It depends on what you want the bytes FOR

This is because, as Tyler so aptly said , “Strings aren’t pure data. They also have information .” In this case, the information is an encoding that was assumed when the string was created.

Assuming that you have binary data (rather than text) stored in a string

This is based off of OP’s comment on his own question, and is the correct question if I understand OP’s hints at the use-case.

Storing binary data in strings is probably the wrong approach because of the assumed encoding mentioned above! Whatever program or library stored that binary data in a string (instead of a byte[] array which would have been more appropriate) has already lost the battle before it has begun. If they are sending the bytes to you in a REST request/response or anything that must transmit strings, Base64 would be the right approach.

If you have a text string with an unknown encoding

Everybody else answered this incorrect question incorrectly.

If the string looks good as-is, just pick an encoding (preferably one starting with UTF), use the corresponding System.Text.Encoding.???.GetBytes() function, and tell whoever you give the bytes to which encoding you picked.