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".
+6
A:
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));
Thomas Levesque
2010-08-08 23:02:50
Just bumped into this question. A nice toy problem... good for an interview. I thought I'd give it a shot before reading the answers. Matched your second approach virtually term for term. I too am addicted to LINQ! +1
spender
2010-08-09 00:06:50
A:
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;
}
jwsample
2010-08-08 23:18:28
You would want to go from a byte array to the binary represenation. A char is a 16 bit data type, so you would chop off the top eight bits of each character code. Also, don't use += to build a string, it scales terribly badly, use a StringBuilder instead.
Guffa
2010-08-08 23:36:35
+3
A:
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.
Maciej Hehl
2010-08-08 23:21:57
This assumes that the string length is a multiple of 8... But you're right, it is probably easier to understand that way. I guess I'm totally addicted to LINQ ;)
Thomas Levesque
2010-08-08 23:30:06
Hmm. I'd argue that the LINQ is more understandable. It describes concisely what is being done without describing the (noisy) steps to acheive that goal. It has a much higher content to noise ratio.
spender
2010-08-09 00:04:11
@spender Sure LINQ is a nice tool for uses it was meant for, but for this simple and straightforward case? Come on, Thomas's code is longer, creates at least 4 enumerable objects, one intermediate array of strings, 5 delegates, and an anonymous reference type for every digit '0' or '1'. This is insane.
Maciej Hehl
2010-08-09 17:48:33
A:
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);
theburningmonk
2010-08-09 21:23:59