Converting a Byte Array into a delimited string - c#

I´m trying to convert a byte array to a delimited by comma string. I just want the values of de bytes into a string so I cand send a string to another pc via TCP.
This is the code that i´m running now and it´s working but it´s too slow (the byte array has 50000 elements). Do you have any better idea?.
Thanks.
byte[] bytes = (byte[])dt.Rows[0]["LNL_BLOB"];
string foto="";
foreach (byte b in bytes)
{
foto = foto + "," + b.ToString();
}

Use StringBuilder when doing lots of string operations.
In this special case, you can also use string.Join:
string foto = string.Join(",", bytes);

Well, you're allocating 100000 strings (half from the ToString() calls, half for the intermediate strings). Have you never heard about the dangers of string concatenation, and the purpose of StringBuilder?
E.g.
byte[] bytes = (byte[])dt.Rows[0]["LNL_BLOB"];
System.Text.StringBuilder foto=new System.Text.StringBuilder();
foreach (byte b in bytes)
{
foto.AppendFormat(",{0}",b);
}
return foto.ToString(); /* Or however you're using your string now */

You could use Convert.ToBase64String rather than iterating through the bytes yourself.
byte[] data = // whatever you do to get the bytes
string sData = Convert.ToBase64String(data);
Here is the method documentation.
When you wanted to get your byte array back from the string, simply use the Convert.FromBase64String ala
byte[] imageData = Convert.FromBase64String(sData);

Use a StringBuilder it is more efficient for concat on strings.
byte[] bytes = (byte[])dt.Rows[0]["LNL_BLOB"];
StringBuilder foto = new StringBuilder();
for(int i = 0; i < bytes.Length; i++) {
foto.Append(bytes[i].ToString());
if (i != (bytes.Length - 1)) foto.Append(",");
}

You can parallelize the loop and process different areas of the array in parallel and reassemble the results. And, as others have mentioned, use StringBuilder.

Related

Md5 return the raw bytes instead of the hex

I have some PHP code and I want to make it in c#.
My code in PHP :
$md5raw = md5($str2hash, true);
My code in c# :
static string GetMd5Hash(MD5 md5Hash, string input)
{
byte[] data = md5Hash.ComputeHash(Encoding.UTF8.GetBytes(input));
// Create a new Stringbuilder to collect the bytes
// and create a string.
StringBuilder sBuilder = new StringBuilder();
// Loop through each byte of the hashed data
// and format each one as a hexadecimal string.
for (int i = 0; i < data.Length; i++)
{
sBuilder.Append(data[i].ToString("x2"));
}
// Return the hexadecimal string.
return sBuilder.ToString();
}
the result of this two codes is not identical
PHP:�賞�}��+X�6�
C#:0f9de8b39ee7187d92bb2b5817bb36ee
What should I change in my c# code?
If you want just the byte array, skip the conversion:
static byte[] GetMd5Hash(MD5 md5Hash, string input)
{
return md5Hash.ComputeHash(Encoding.UTF8.GetBytes(input));
}
UPDATE:
You definitively should change your PHP function to return encoded data and use the same encoding in .net (C#).
What you want is to get an string with binary data, but with that you will lose information due to reencoding of the binary data during transfer.
static string GetMd5Hash(MD5 md5Hash, string input)
{
// BUG: This code probably will lose information
return Encoding.ASCII.GetString(md5Hash.ComputeHash(Encoding.UTF8.GetBytes(input)));
}
The way you should do is to use your C# function as in your question and use this as your PHP function:
$md5raw = bin2hex(md5($str2hash, true));

String representation of byte array

I have a string that represents a byte
string s = "\x00af";
I write this string to a file so the file contains the literal "\x00af" and not the byte it represents, later I read this string from the file, how can I now treat this string as byte again (and not the literal)?
Here is a sample code:
public static void StringAndBytes()
{
string s = "\x00af";
byte[] b = Encoding.ASCII.GetBytes(s);
// Length would be 1
Console.WriteLine(b.Length);
// Write this to a file as literal
StreamWriter sw = new StreamWriter("c:\\temp\\MyTry.txt");
sw.WriteLine("\\x00af");
sw.Close();
// Read it from the file
StreamReader sr = new StreamReader("c:\\temp\\MyTry.txt");
s = sr.ReadLine();
sr.Close();
// Get the bytes and Length would be 6, as it treat the string as string
// and not the byte it represents
b = Encoding.ASCII.GetBytes(s);
Console.WriteLine(b.Length);
}
Any idea on how I convert the string from being a text to the string representing a byte? Thx!
Is it a requirement for the file content to have the string literal? If no, then you might want to write the byte[] b array directly to the file. That way when you read it, it is exactly, what you wrote.
byte[] b = Encoding.UTF32.GetBytes(s);
File.WriteAllBytes ("c:\\temp\\MyTry.txt", b);
b = File.ReadAllBytes ("c:\\temp\\MyTry.txt");
s = Encoding.UTF32.GetString (b);
If you need the file content to have the string literal, while being able to convert it to the original text written, you will have to choose the right encoding. I believe UTF32 to be the best.
b = new byte[4];
b[0] = Byte.Parse(s.Substring(2), System.Globalization.NumberStyles.AllowHexSpecifier);
string v = Encoding.UTF32.GetString(b);
string w = "\x00af";
if (v != w)
MessageBox.Show("Diff [" + w + "] = [" + v + "] ");
else
MessageBox.Show("Same");
Not sure if I understand the question correctly, but you're not writing the string s to the file. You have an extra \ in your WriteLine statement! WriteLine("\\x00af") writes the characters \, x, 0, 0, a and f, since the first \ acts as an escape to the second one ...
Did you mean
sw.WriteLine("\x00af");
or
sw.WriteLine(s);
instead? This works as expected in my tests.
Use the Encoding.ASCII.GetString(byte[]) method. It is also available from all the others encoding. Make sure you always use the same encoding to decode the byte[] as you used to encode it or you won't get the same value every time.
Here's an example.
Just parse a string representing each byte:
Byte b = Byte.Parse(s);

String to raw byte array

I have a string which contains binary data (non-text data).
How do I convert this to a raw byte array?
A string in C# - by definition - does not contain binary data. It consists of a sequence of Unicode characters.
If your string contains only Unicode characters in the ASCII (7-bit) character set, you can use Encoding.ASCII to convert the string to bytes:
byte[] result = Encoding.ASCII.GetBytes(input);
If you have a string that contains Unicode characters in the range u0000-u00ff and want to interpret these as bytes, you can cast the characters to bytes:
byte[] result = new byte[input.Length];
for (int i = 0; i < input.Length; i++)
{
result[i] = (byte)input[i];
}
It is a very bad idea to store binary data in a string. However, if you absolutely must do so, you can convert a binary string to a byte array using the 1252 code page. Do not use code page 0 or you will lose some values when in foreign languages. It just so happens that code page 1252 properly converts all byte values from 0 to 255 to Unicode and back again.
There have been some poorly written VB6 programs that use binary strings. Unfortunately some are so many lines of code that it is almost impossible to convert it all to byte() arrays in one go.
You've been warned. Use at your own peril:
Dim bData() As Byte
Dim sData As String
'convert string binary to byte array
bData = System.Text.Encoding.GetEncoding(1252).GetBytes(sData)
'convert byte array to string binary
sData = System.Text.Encoding.GetEncoding(1252).GetString(bData)
Here is one way:
public static byte[] StrToByteArray(string str)
{
System.Text.ASCIIEncoding encoding=new System.Text.ASCIIEncoding();
return encoding.GetBytes(str);
}
System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
byte[] theBytes = encoding.GetBytes("Some String");
Note, there are other encoding formats you may want to use.

Converting a md5 hash byte array to a string

How can I convert the hashed result, which is a byte array, to a string?
byte[] bytePassword = Encoding.UTF8.GetBytes(password);
using (MD5 md5 = MD5.Create())
{
byte[] byteHashedPassword = md5.ComputeHash(bytePassword);
}
I need to convert byteHashedPassword to a string.
public static string ToHex(this byte[] bytes, bool upperCase)
{
StringBuilder result = new StringBuilder(bytes.Length*2);
for (int i = 0; i < bytes.Length; i++)
result.Append(bytes[i].ToString(upperCase ? "X2" : "x2"));
return result.ToString();
}
You can then call it as an extension method:
string hexString = byteArray.ToHex(false);
I always found this to be the most convenient:
string hashPassword = BitConverter.ToString(byteHashedPassword).Replace("-","");
For some odd reason BitConverter likes to put dashes between bytes, so the replace just removes them.
Update:
If you prefer "lowercase" hex, just do a .ToLower() and boom.
Do note that if you are doing this as a tight loop and many ops this could be expensive since there are at least two implicit string casts and resizes going on.
You can use Convert.ToBase64String and Convert.FromBase64String to easily convert byte arrays into strings.
If you're in the 'Hex preference' camp you can do this. This is basically a minimal version of the answer by Philippe Leybaert.
string.Concat(hash.Select(x => x.ToString("X2")))
B1DB2CC0BAEE67EA47CFAEDBF2D747DF
Well as it is a hash, it has possibly values that cannot be shown in a normal string, so the best bet is to convert it to Base64 encoded string.
string s = Convert.ToBase64String(bytes);
and use
byte[] bytes = Convert.FromBase64(s);
to get the bytes back.
Well, you could use the string constructor that takes bytes and an encoding, but you'll likely get a difficult to manage string out of that since it could contain lots of fun characters (null bytes, newlines, control chars, etc)
The best way to do this would be to encode it with base 64 to get a nice string that's easy to work with:
string s = Convert.ToBase64String(bytes);
And to go from that string back to a byte array:
byte[] bytes = Convert.FromBase64String(s);
I know this is an old question, but I thought I would add you can use the built-in methods (I'm using .NET 6.0):
Convert.ToBase64String(hashBytes); (Others have already mentioned this)
Convert.ToHexString(hashBytes);
For anyone interested a Nuget package I created called CryptoStringify allows you to convert a string to a hashed string using a nice clean syntax, without having to play around with byte arrays:
using (MD5 md5 = MD5.Create())
{
string strHashedPassword = md5.Hash(password);
}
It's an extension method on HashAlgorithm and KeyedHashAlgorithm so works on SHA1, HMACSHA1, SHA256 etc too.
https://www.nuget.org/packages/cryptostringify

In C#, how do I convert an array of bytes into a string of hex numbers?

In C#, what is the tidiest way to convert an array of bytes into a string of hex numbers?
BitConverter.ToString http://msdn.microsoft.com/en-us/library/system.bitconverter.tostring.aspx
You'll get hyphens between bytes in the string, but they are easily removed.
This should work... BitConverter is better, but this gives you more control (no hyphens) and you can get fancy with lambdas if you so wished :)
public string byteToHex(byte[] byteArray) {
StringBuilder result = new StringBuilder();
foreach (byte b in byteArray) {
result.AppendString(b.ToString("X2"));
}
return result.ToString();
}
Here's an extension I use when I need lowercase hex. e.g. Facebook requires lowercase for signing POST data.
private static string ToLowerCaseHexString(this IEnumerable<byte> hash)
{
return hash
.Select(b => String.Format("{0:x2}",
b))
.Aggregate((a, b) => a + b);
}
Might be quicker using a StringBuilder over linq .Aggregate, but the byte arrays I pass are short.

Categories