How do you convert a string such as "01110100011001010111001101110100" to a byte array then used File.WriteAllBytes such that the exact binary string is the binary of the file. In this case it would be the the text "test".
5 Answers
In case you don't have this LINQ fetish, so common lately, you can try the normal way
string input ....
int numOfBytes = input.Length / 8;
byte[] bytes = new byte[numOfBytes];
for(int i = 0; i < numOfBytes; ++i)
{
bytes[i] = Convert.ToByte(input.Substring(8 * i, 8), 2);
}
File.WriteAllBytes(fileName, bytes);
LINQ is great but there must be some limits.
4 Comments
input.Length / 8 is not properly rounded, if the double value is 1.75, numOfBytes is 1. Beware of that!You could start by splitting the string into a sequence of 8-character strings, then convert those strings to bytes, and eventually write the bytes to a file
string input = "01110100011001010111001101110100";
var bytesAsStrings =
input.Select((c, i) => new { Char = c, Index = i })
.GroupBy(x => x.Index / 8)
.Select(g => new string(g.Select(x => x.Char).ToArray()));
byte[] bytes = bytesAsStrings.Select(s => Convert.ToByte(s, 2)).ToArray();
File.WriteAllBytes(fileName, bytes);
EDIT: here's another way to split the string into 8-character chunks, perhaps a bit simpler :
int nBytes = (int)Math.Ceiling(input.Length / 8m);
var bytesAsStrings =
Enumerable.Range(0, nBytes)
.Select(i => input.Substring(8 * i, Math.Min(8, input.Length - 8 * i)));
If you know that the length of the string is a multiple of 8, you can make it even simpler :
int nBytes = input.Length / 8;
var bytesAsStrings =
Enumerable.Range(0, nBytes)
.Select(i => input.Substring(8 * i, 8));
1 Comment
A bit late, but here's my 2 cents:
var binaryStr = "01110100011001010111001101110100";
var byteArray = Enumerable.Range(0, int.MaxValue/8)
.Select(i => i*8)
.TakeWhile(i => i < binaryStr.Length)
.Select(i => binaryStr.Substring(i, 8))
.Select(s => Convert.ToByte(s, 2))
.ToArray();
File.WriteAllBytes("C:\temp\test.txt", byteArray);
Comments
Actually the answer by @Maciej is not correct. As @Phate01 noticed the numOfBytes is correct only for input length which is a power of 8. The second thing is that the byte array should be populated from n to 0 index not the opposite way. Here's the code example:
var bits = "000011110000001000";
var numOfBytes = (int)Math.Ceiling(bits.Length / 8m);
var bytes = new byte[numOfBytes];
var chunkSize = 8;
for (int i = 1; i <= numOfBytes; i++)
{
var startIndex = bits.Length - 8 * i;
if (startIndex < 0)
{
chunkSize = 8 + startIndex;
startIndex = 0;
}
bytes[numOfBytes - i] = Convert.ToByte(bits.Substring(startIndex, chunkSize), 2);
}
This can be improved to get rid of the if statetment but in this form it's more understandable.
Comments
The other answers have you covered, but just for fun I wrote the opposite. Going from the string to the ascii binary representation:
private static string StringToAsciiBin(string s)
{
string output = "";
foreach (char c in s.ToCharArray())
{
for (int i = 128; i >= 1; i /=2)
{
if (((int)c & i) > 0)
{
output += "1";
}
else
{
output += "0";
}
}
}
return output;
}
2 Comments
StringBuilder, but if you have "01110100011001010111001101110100" as an input, sorry, that's a string, not a byte[], until you separate it out into blocks of 8.