c# encoding - ¿Cómo convertir UTF-8 byte[]a cadena?




decode utf8 (12)

Tengo una matriz de byte[] que se carga desde un archivo que, por casualidad, contiene UTF-8 . En algún código de depuración, necesito convertirlo en una cadena. ¿Hay un forro que hará esto?

Debajo de las coberturas, debe ser solo una asignación y una copia , por lo que incluso si no se implementa, debería ser posible.


Answers

Utilizando (byte)b.ToString("x2") , Salidas b4b5dfe475e58b67

public static class Ext {

    public static string ToHexString(this byte[] hex)
    {
        if (hex == null) return null;
        if (hex.Length == 0) return string.Empty;

        var s = new StringBuilder();
        foreach (byte b in hex) {
            s.Append(b.ToString("x2"));
        }
        return s.ToString();
    }

    public static byte[] ToHexBytes(this string hex)
    {
        if (hex == null) return null;
        if (hex.Length == 0) return new byte[0];

        int l = hex.Length / 2;
        var b = new byte[l];
        for (int i = 0; i < l; ++i) {
            b[i] = Convert.ToByte(hex.Substring(i * 2, 2), 16);
        }
        return b;
    }

    public static bool EqualsTo(this byte[] bytes, byte[] bytesToCompare)
    {
        if (bytes == null && bytesToCompare == null) return true; // ?
        if (bytes == null || bytesToCompare == null) return false;
        if (object.ReferenceEquals(bytes, bytesToCompare)) return true;

        if (bytes.Length != bytesToCompare.Length) return false;

        for (int i = 0; i < bytes.Length; ++i) {
            if (bytes[i] != bytesToCompare[i]) return false;
        }
        return true;
    }

}

La conversión de un byte[] a una string parece simple, pero cualquier tipo de codificación puede desordenar la cadena de salida. Esta pequeña función simplemente funciona sin ningún resultado inesperado:

private string ToString(byte[] bytes)
{
    string response = string.Empty;

    foreach (byte b in bytes)
        response += (Char)b;

    return response;
}

Un linq de una sola línea para convertir una matriz de bytes byteArrFilename de un archivo a una cadena terminada en cero de estilo C puro ascii sería esta: Práctica para leer cosas como tablas de índice de archivos en formatos de archivo antiguos.

String filename = new String(byteArrFilename.TakeWhile(x => x != 0)
                              .Select(x => x < 128 ? (Char)x : '?').ToArray());

Yo uso '?' como char por defecto para cualquier cosa que no sea puro ascii aquí, pero eso se puede cambiar, por supuesto. Si desea estar seguro de que puede detectarlo, simplemente use '\0' lugar, ya que el TakeWhile al principio garantiza que una cadena construida de esta manera no pueda contener valores '\0' de la fuente de entrada.


Definición:

public static string ConvertByteToString(this byte[] source)
{
    return source != null ? System.Text.Encoding.UTF8.GetString(source) : null;
}

Utilizando:

string result = input.ConvertByteToString();

Prueba esto:

string myresult = System.Text.Encoding.UTF8.GetString(byteArray);

También existe la clase UnicodeEncoding, de uso bastante simple:

ByteConverter = new UnicodeEncoding();
string stringDataForEncoding = "My Secret Data!";
byte[] dataEncoded = ByteConverter.GetBytes(stringDataForEncoding);

Console.WriteLine("Data after decoding: {0}", ByteConverter.GetString(dataEncoded));

hier es un resultado en el que no tenías que preocuparte por la codificación. Lo usé en mi clase de red y envié objetos binarios como una cadena con él.

        public static byte[] String2ByteArray(string str)
        {
            char[] chars = str.ToArray();
            byte[] bytes = new byte[chars.Length * 2];

            for (int i = 0; i < chars.Length; i++)
                Array.Copy(BitConverter.GetBytes(chars[i]), 0, bytes, i * 2, 2);

            return bytes;
        }

        public static string ByteArray2String(byte[] bytes)
        {
            char[] chars = new char[bytes.Length / 2];

            for (int i = 0; i < chars.Length; i++)
                chars[i] = BitConverter.ToChar(bytes, i * 2);

            return new string(chars);
        }

Hay al menos cuatro formas diferentes de hacer esta conversión.

  1. Codificación GetString
    , pero no podrá recuperar los bytes originales si esos bytes tienen caracteres no ASCII.

  2. BitConverter.ToString
    La salida es una cadena delimitada "-", pero no hay un método incorporado de .NET para convertir la cadena de nuevo a una matriz de bytes.

  3. Convert.ToBase64String
    Puede convertir fácilmente la cadena de salida de nuevo a matriz de bytes utilizando Convert.FromBase64String .
    Nota: la cadena de salida podría contener '+', '/' y '='. Si desea utilizar la cadena en una URL, debe codificarla explícitamente.

  4. HttpServerUtility.UrlTokenEncode
    Puede convertir fácilmente la cadena de salida de nuevo a la matriz de bytes utilizando HttpServerUtility.UrlTokenDecode . La cadena de salida ya es compatible con URL! El inconveniente es que necesita System.Web Assembly si su proyecto no es un proyecto web.

Un ejemplo completo:

byte[] bytes = { 130, 200, 234, 23 }; // A byte array contains non-ASCII (or non-readable) characters

string s1 = Encoding.UTF8.GetString(bytes); // ���
byte[] decBytes1 = Encoding.UTF8.GetBytes(s1);  // decBytes1.Length == 10 !!
// decBytes1 not same as bytes
// Using UTF-8 or other Encoding object will get similar results

string s2 = BitConverter.ToString(bytes);   // 82-C8-EA-17
String[] tempAry = s2.Split('-');
byte[] decBytes2 = new byte[tempAry.Length];
for (int i = 0; i < tempAry.Length; i++)
    decBytes2[i] = Convert.ToByte(tempAry[i], 16);
// decBytes2 same as bytes

string s3 = Convert.ToBase64String(bytes);  // gsjqFw==
byte[] decByte3 = Convert.FromBase64String(s3);
// decByte3 same as bytes

string s4 = HttpServerUtility.UrlTokenEncode(bytes);    // gsjqFw2
byte[] decBytes4 = HttpServerUtility.UrlTokenDecode(s4);
// decBytes4 same as bytes

Una solución general para convertir de una matriz de bytes a una cadena cuando no conoce la codificación:

static string BytesToStringConverted(byte[] bytes)
{
    using (var stream = new MemoryStream(bytes))
    {
        using (var streamReader = new StreamReader(stream))
        {
            return streamReader.ReadToEnd();
        }
    }
}

Alternativamente:

 var byteStr = Convert.ToBase64String(bytes);

string result = System.Text.Encoding.UTF8.GetString(byteArray);

Depende de lo que quieras para los bytes.

Esto se debe a que, como Tyler lo said tan acertadamente , "las cadenas no son datos puros. También tienen information ". En este caso, la información es una codificación que se asumió cuando se creó la cadena.

Suponiendo que tiene datos binarios (en lugar de texto) almacenados en una cadena

Esto se basa en el comentario de OP sobre su propia pregunta, y es la pregunta correcta si entiendo las sugerencias de OP sobre el caso de uso.

¡Almacenar datos binarios en cadenas es probablemente el enfoque incorrecto debido a la supuesta codificación mencionada anteriormente! Cualquier programa o biblioteca que haya almacenado esos datos binarios en un string(en lugar de una byte[]matriz que hubiera sido más apropiado) ya ha perdido la batalla antes de que haya comenzado. Si le envían los bytes en una solicitud / respuesta REST o cualquier cosa que deba transmitir cadenas, Base64 sería el enfoque correcto.

Si tienes una cadena de texto con una codificación desconocida

Todos los demás respondieron esta pregunta incorrecta incorrectamente.

Si la cadena se ve bien como está, simplemente elija una codificación (preferiblemente una que comience con UTF), use la System.Text.Encoding.???.GetBytes()función correspondiente y dígale a quien le da los bytes a la codificación que eligió.





c# .net arrays string type-conversion