Преобразование byte[] в String и обратно С#

Я пытаюсь преобразовать byte[] в строку и обратно, используя Encoding.Unicode. Иногда Encoding.Unicode может преобразовать byte[] в строку, а иногда вывод равен != вводу. Что я делаю не так?

Спасибо за вашу помощь.

public static void Main(string[] args)
{
    Random rnd = new Random();
    while(true)
    {
        Int32 random = rnd.Next(10, 20);
        Byte[] inBytes = new Byte[random];
        for(int i = 0; i < random; i++)
            inBytes[i] = (Byte)rnd.Next(0, 9);

        String inBytesString = Encoding.Unicode.GetString(inBytes, 0, inBytes.Length);
        Byte[] outBytes = Encoding.Unicode.GetBytes(inBytesString);

        if(inBytes.Length != outBytes.Length)
            throw new Exception("?");
        else
        {
            for(int i = 0; i < inBytes.Length; i++)
            {
                if(inBytes[i] != outBytes[i])
                    throw new Exception("?");
            }
        }
        Console.WriteLine("OK");
    }
}

person musium    schedule 09.10.2012    source источник
comment
Что ж, некоторые массивы случайных байтов не будут действительным юникодом, поэтому иногда это не сработает. Если вы начнете со случайной строки и переместите ее через массив байтов, это будет работать каждый раз.   -  person Jodrell    schedule 09.10.2012


Ответы (3)


Вы не можете использовать кодировку для этого: вы должны использовать что-то вроде Convert.ToBase64String / Convert.FromBase64String.

Кодирование предполагает, что byte[] отформатирован в соответствии с определенными правилами, что не относится к случайному нестроковому byte[].

Чтобы обобщить:

Кодировка превращает произвольную строку в/из форматированного байта[]

Base-64 превращает произвольный byte[] в/из форматированной строки

person Marc Gravell    schedule 09.10.2012

you cannot use encoding use base64

используя base64 u можно безопасно преобразовывать байты в строку и обратно

base64 guaranteed to not to get "invalid" unicode sequences как:
первая половина суррогатной пары без второй половины используется так:

string base64 = Convert.ToBase64String(bytes);
byte[] bytes = Convert.FromBase64String(base64);
person Ravindra Bagale    schedule 09.10.2012
comment
строго говоря, base64 - это кодировка. - person Jodrell; 09.10.2012

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

protected bool isImageCMYK(HttpPostedFile image, Stream fileContent)
    {
            //creating byte array
        byte[] imageToByteArray = new byte[image.ContentLength];

            //filling the byte array
        fileContent.Read(imageToByteArray, 0 , image.ContentLength);

            //convering byte array back to a readable string
        UTF8Encoding byteToString = new UTF8Encoding();
        string imageString = byteToString.GetString(imageToByteArray);

        return imageString.ToLower().Contains("cmyk");
    }

вот отредактированный код, который приводит к выводу «ОК»

public static void Main(string[] args)
        {
            Random rnd = new Random();
            while (true)
            {
                Int32 random = rnd.Next(10, 20);
                Byte[] inBytes = new Byte[random];
                for (int i = 0; i < random; i++)
                    inBytes[i] = (Byte)rnd.Next(0, 9);

                UTF8Encoding inBytesString = new UTF8Encoding(); 
                string byteString = inBytesString.GetString(inBytes, 0, inBytes.Length);
                //Byte[] outBytes = Encoding.Unicode.GetBytes(inBytesString);
                Byte[] outBytes = inBytesString.GetBytes(byteString);

                if (inBytes.Length != outBytes.Length)
                    throw new Exception("?");
                else
                {
                    for (int i = 0; i < inBytes.Length; i++)
                    {
                        if (inBytes[i] != outBytes[i])
                            throw new Exception("?");
                    }
                }
                Console.WriteLine("OK");
            }
person Andrew Brower    schedule 09.10.2012
comment
Если входящие данные являются двоичными данными (а не данными UTF8), это недопустимая реализация. Это только правильно, если данные представляют собой текст UTF-8 (или текст ASCII). - person Marc Gravell; 09.10.2012
comment
Так что, если вы используете целые числа, как указано выше, все должно быть в порядке, верно? - person Andrew Brower; 09.10.2012
comment
Целые числа как? Строки целочисленных значений? целые числа закодированы в двоичный код? Если да, то какая кодировка? 4-байтовый LE? 4-байтовый БЭ? вариант? Что-то другое? - person Marc Gravell; 09.10.2012
comment
прочитал неправильно, но я отредактировал свой код на примере и получил идентичные массивы байтов - person Andrew Brower; 09.10.2012
comment
да, но это совпадение, потому что однобайтовые значения 0-9 происходят для всех допустимы в UTF-8. Теперь попробуйте выполнить циклический обмен тремя байтами (шестнадцатеричными) ff ff ff. Или просто один (шестнадцатеричный) ff. - person Marc Gravell; 09.10.2012