Преобразование строки в байтовый массив и наоборот - PullRequest
0 голосов
/ 09 января 2019

Преобразование строки в байтовый массив и последующее изменение обратно иногда не будет возвращать ту же строку:

RandomNumberGenerator gen = new RNGCryptoServiceProvider();
byte[] randomBytes = new byte[32];
gen.GetBytes(randomBytes);

В некоторых случаях (или в любой другой кодировке, кроме Юникода):

randomBytes != Encoding.Unicode.GetBytes(Encoding.Unicode.GetString(randomBytes));

Я хотел бы знать, как сделать этот метод и получить тот же результат наверняка . Заранее спасибо

Ответы [ 2 ]

0 голосов
/ 09 января 2019

Произвольный байтовый массив необязательно кодирует действительную строку Unicode (см. https://en.wikipedia.org/wiki/UTF-16), например,

  byte[] before = new byte[] { 0xA6, 0xDD };
  byte[] after = Encoding.Unicode.GetBytes(Encoding.Unicode.GetString(before));

  if (!before.SequenceEqual(after))
    Console.Write(string.Join(Environment.NewLine,
      $"before: {string.Join(" ", before.Select(b => b.ToString("x2")))}",
      $"after:  {string.Join(" ", after.Select(b => b.ToString("x2")))}"));

Итог:

before: a6 dd
after:  fd ff

Если вы хотите сгенерировать эти строки, вы можете изменить свой код на

while (true) {
  using (RandomNumberGenerator gen = new RNGCryptoServiceProvider()) {
    byte[] randomBytes = new byte[32];
    gen.GetBytes(randomBytes);

    byte[] after = Encoding.Unicode.GetBytes(Encoding.Unicode.GetString(randomBytes));

    if (!randomBytes.SequenceEqual(after)) {
      Console.Write(string.Join(" ", randomBytes) + 
                    Environment.NewLine + 
                    string.Join(" ", after));

      break;
    }
  }
}

Возможный исход:

166 8 99 175 188 233 240 219 64 143 26 87 157 209 205 219 27 169 239 67 99 170 172 226 254 56 168 168 64 222 178 15
166 8 99 175 188 233 253 255 64 143 26 87 157 209 253 255 27 169 239 67 99 170 172 226 254 56 168 168 253 255 178 15
                     ^
                     Difference

Обратите внимание, что мы должны сравнивать массивы с SequenceEqual.

Если вы хотите закодировать массив , вы можете сделать это с помощью string.Join:

byte[] array = ...

// Something like "166 8 99 175 188 233 240 219 ... 64 222 178 15"
string encoded = string.Join(" ", array);

byte[] back = encoded
  .Split(' ')
  .Select(item => byte.Parse(item))
  .ToArray();
0 голосов
/ 09 января 2019

Возможно, вы ищете не кодировку текста, а формат сериализации. Текстовые кодировки предназначены для текста. Обрабатываемые вами байты являются случайными байтами.

Работает ли Base64 (Convert.ToBase64String) у вас?

Вы также можете вставить байты в символы (new string(myBytes.Select(b => (char)b).ToArray())). Это приведет к нечитаемым строкам, которые могут быть искажены другими системами. Вероятно, не правильный путь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...