Reputation: 33
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
Upvotes: 3
Views: 415
Reputation: 186668
Arbitrary byte array does not necessary encodes a valid Unicode string (see https://en.wikipedia.org/wiki/UTF-16 for details), e.g.
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();
Upvotes: 1
Reputation: 171178
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.
Upvotes: 2