简体   繁体   中英

Converting String to Byte Array and vice versa

Converting a string to a byte array and then changing back will sometimes wont return the same string:

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

In some cases (or any kind of encoding other than unicode):

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

I'd like to know how to do this method and get the same result for sure . Thanks in advance

Probably, you are not looking for a text encoding but a serialization format. Text encodings are meant for text. The bytes you are processing are random bytes.

Does Base64 ( Convert.ToBase64String ) work for you?

You could also jam the bytes into chars ( new string(myBytes.Select(b => (char)b).ToArray()) ). This will produce unreadable strings that are prone to being mangled by other systems. Likely not the right path.

Arbitrary byte array does not necessary encodes a valid Unicode string (see https://en.wikipedia.org/wiki/UTF-16 for details), eg

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

Outcome:

before: a6 dd
after:  fd ff

If you want to generate these strings you can modify your code into

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

Possible outcome:

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

Please, note that we should compare arrays with SequenceEqual .

If you want to encode an array , you can do it with a help of 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();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM