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".
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.
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));
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);
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.
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;
}
Related
This question already has answers here:
How do you convert a byte array to a hexadecimal string, and vice versa?
(53 answers)
Closed 5 years ago.
Can we convert a hex string to a byte array using a built-in function in C# or do I have to make a custom method for this?
Here's a nice fun LINQ example.
public static byte[] StringToByteArray(string hex) {
return Enumerable.Range(0, hex.Length)
.Where(x => x % 2 == 0)
.Select(x => Convert.ToByte(hex.Substring(x, 2), 16))
.ToArray();
}
I did some research and found out that byte.Parse is even slower than Convert.ToByte.
The fastest conversion I could come up with uses approximately 15 ticks per byte.
public static byte[] StringToByteArrayFastest(string hex) {
if (hex.Length % 2 == 1)
throw new Exception("The binary key cannot have an odd number of digits");
byte[] arr = new byte[hex.Length >> 1];
for (int i = 0; i < hex.Length >> 1; ++i)
{
arr[i] = (byte)((GetHexVal(hex[i << 1]) << 4) + (GetHexVal(hex[(i << 1) + 1])));
}
return arr;
}
public static int GetHexVal(char hex) {
int val = (int)hex;
//For uppercase A-F letters:
//return val - (val < 58 ? 48 : 55);
//For lowercase a-f letters:
//return val - (val < 58 ? 48 : 87);
//Or the two combined, but a bit slower:
return val - (val < 58 ? 48 : (val < 97 ? 55 : 87));
}
// also works on .NET Micro Framework where (in SDK4.3) byte.Parse(string) only permits integer formats.
The following code changes the hexadecimal string to a byte array by parsing the string byte-by-byte.
public static byte[] ConvertHexStringToByteArray(string hexString)
{
if (hexString.Length % 2 != 0)
{
throw new ArgumentException(String.Format(CultureInfo.InvariantCulture, "The binary key cannot have an odd number of digits: {0}", hexString));
}
byte[] data = new byte[hexString.Length / 2];
for (int index = 0; index < data.Length; index++)
{
string byteValue = hexString.Substring(index * 2, 2);
data[index] = byte.Parse(byteValue, NumberStyles.HexNumber, CultureInfo.InvariantCulture);
}
return data;
}
I think this may work.
public static byte[] StrToByteArray(string str)
{
Dictionary<string, byte> hexindex = new Dictionary<string, byte>();
for (int i = 0; i <= 255; i++)
hexindex.Add(i.ToString("X2"), (byte)i);
List<byte> hexres = new List<byte>();
for (int i = 0; i < str.Length; i += 2)
hexres.Add(hexindex[str.Substring(i, 2)]);
return hexres.ToArray();
}
I want to input a series of Hex numbers into a textBox and when the user hits a button separate each byte with a comma. AAFFBCEE becomes AA,FF,BC,EE (no comma on last byte). how can I convert a string value to this format?
string temp = "aaff4455";
string temp2 = "";
int size = temp.Length;
for (int i = 0; i < size; i += 2)
{
temp2 += temp.Substring(i, 2);
if ((i+2) < size)
temp2 += ",";
}
Why not use a 1-liner?
var str = "AABBCCDD";
var result = "";
str.ToCharArray()
.Select((c, i) => new { i, c })
.ToList()
.ForEach(c => result += (c.i > 0 && c.i % 2 == 0) ? "," + c.c : c.c.ToString());
(I'm still learning Linq so be nice!)
I've a List with either 1, 2 or 4 hex values saved as decimal values. I want to convert them into one decimal number.
Example:
List<Byte> values: 1 and 95 (= 0x01, 0x5F)
I want to convert the list into one decimal number:
0x015F = 351
How can I do that?
var result = 0;
var i = 0;
foreach (var val in values)
{
result = (result << i) + (int)val;
i += 8;
}
Modern, LINQ-based way (old-fashined C-programmers can turn in one's grave):
List<Byte> list = new List<byte>() { 0x01, 0x5F };
var output = list.Select(x => (int)x)
.Reverse()
.Aggregate((x, y) => (int)0x100 * y + (int)x);
With BitConverter class, you can do:
var values = new List<byte> { 0x01, 0x5F, };
byte[] arr = new byte[4];
for (int i = 0; i < values.Count; ++i)
arr[values.Count - 1 - i] = values[i];
int result = BitConverter.ToInt32(arr, 0);
You fill the array arr backwards from the middle, as seen.
If the numbers can be greater (i.e. the List<> can be up to 8 bytes long), use ulong (never negative), for example:
var values = new List<byte> { 0x01, 0x5F, };
byte[] arr = new byte[8];
for (int i = 0; i < values.Count; ++i)
arr[values.Count - 1 - i] = values[i];
ulong result = BitConverter.ToUInt64(arr, 0);
If the List<> can be arbitrarily long, use new BigInteger(arr) (requires csproj reference to System.Numerics.dll assembly).
My goal is to be able to convert a string into binary code that is still a string. I am able to turn the string into byte[] but not back to a string without decoding it.
You can use the Convert method for that:
byte [] bytesToEncode = Encoding.UTF8.GetBytes (inputText);
string encodedText = Convert.ToBase64String (bytesToEncode);
If you can encode/decode a byte, e.g.
private static String ToBinary(Byte value) {
StringBuilder Sb = new StringBuilder(8);
Sb.Length = 8;
for (int i = 0; i < 8; ++i) {
Sb[7 - i] = (Char) ('0' + value % 2);
value /= 2;
}
return Sb.ToString();
}
private static Byte FromBinary(String value) {
int result = 0;
for (int i = 0; i < value.Length; ++i)
result = result * 2 + value[i] - '0';
return (Byte) result;
}
You can easily encode/decode a whole string:
// Encoding...
String source = "abc";
// 011000010110001001100011
String result = String.Join("", UTF8Encoding.UTF8.GetBytes(source).Select(x => ToBinary(x)));
...
// Decoding...
List<Byte> codes = new List<Byte>();
for (int i = 0; i < result.Length; i += 8)
codes.Add(FromBinary(result.Substring(i, 8)));
// abc
String sourceBack = UTF8Encoding.UTF8.GetString(codes.ToArray());
use
string str = "Welcome";
byte []arr = System.Text.Encoding.ASCII.GetBytes(str);
This question already has answers here:
How do you convert a byte array to a hexadecimal string, and vice versa?
(53 answers)
Closed 5 years ago.
Can we convert a hex string to a byte array using a built-in function in C# or do I have to make a custom method for this?
Here's a nice fun LINQ example.
public static byte[] StringToByteArray(string hex) {
return Enumerable.Range(0, hex.Length)
.Where(x => x % 2 == 0)
.Select(x => Convert.ToByte(hex.Substring(x, 2), 16))
.ToArray();
}
I did some research and found out that byte.Parse is even slower than Convert.ToByte.
The fastest conversion I could come up with uses approximately 15 ticks per byte.
public static byte[] StringToByteArrayFastest(string hex) {
if (hex.Length % 2 == 1)
throw new Exception("The binary key cannot have an odd number of digits");
byte[] arr = new byte[hex.Length >> 1];
for (int i = 0; i < hex.Length >> 1; ++i)
{
arr[i] = (byte)((GetHexVal(hex[i << 1]) << 4) + (GetHexVal(hex[(i << 1) + 1])));
}
return arr;
}
public static int GetHexVal(char hex) {
int val = (int)hex;
//For uppercase A-F letters:
//return val - (val < 58 ? 48 : 55);
//For lowercase a-f letters:
//return val - (val < 58 ? 48 : 87);
//Or the two combined, but a bit slower:
return val - (val < 58 ? 48 : (val < 97 ? 55 : 87));
}
// also works on .NET Micro Framework where (in SDK4.3) byte.Parse(string) only permits integer formats.
The following code changes the hexadecimal string to a byte array by parsing the string byte-by-byte.
public static byte[] ConvertHexStringToByteArray(string hexString)
{
if (hexString.Length % 2 != 0)
{
throw new ArgumentException(String.Format(CultureInfo.InvariantCulture, "The binary key cannot have an odd number of digits: {0}", hexString));
}
byte[] data = new byte[hexString.Length / 2];
for (int index = 0; index < data.Length; index++)
{
string byteValue = hexString.Substring(index * 2, 2);
data[index] = byte.Parse(byteValue, NumberStyles.HexNumber, CultureInfo.InvariantCulture);
}
return data;
}
I think this may work.
public static byte[] StrToByteArray(string str)
{
Dictionary<string, byte> hexindex = new Dictionary<string, byte>();
for (int i = 0; i <= 255; i++)
hexindex.Add(i.ToString("X2"), (byte)i);
List<byte> hexres = new List<byte>();
for (int i = 0; i < str.Length; i += 2)
hexres.Add(hexindex[str.Substring(i, 2)]);
return hexres.ToArray();
}