I have a problem about converting binary to hex then hex to binary.
For example I have an image file. First I want to convert that image to a hex string, then I want to insert this hex string to database. When a user wants to get that image file, the program has to read the hex string from the databasae, then converts to an image file.
Is it possible in C# ?
I have tried some sample methods from StackOverflow but I can't do that. I did an image file but it can't be shown.
I am waiting for your help.
Thank you
Let us know if this helps you out -
private string GetHexStringFromImage(System.Drawing.Image imageToConvert)
{
//Convert image it to byte-array
byte[] byteArray;
using (MemoryStream ms = new MemoryStream())
{
imageToConvert.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
byteArray = ms.ToArray();
}
//Convert byte-array to Hex-string
StringBuilder hexBuilder = new StringBuilder();
foreach (byte b in byteArray)
{
string hexByte = b.ToString("X");
//make sure each byte is represented by 2 Hex digits
string tempString = hexByte.Length % 2 == 0 ? hexByte : hexByte.PadLeft(2, '0');
hexBuilder.Append(tempString);
}
//return Hex-string to save to DB
return hexBuilder.ToString();
}
private System.Drawing.Image GetImageFromHexString(string hexSting)
{
//Convert Hex-string from DB to byte-array
int length = hexSting.Length;
List<byte> byteList = new List<byte>();
//Take 2 Hex digits at a time
for (int i = 0; i < length; i += 2)
{
byte byteFromHex = Convert.ToByte(hexSting.Substring(i, 2), 16);
byteList.Add(byteFromHex);
}
byte[] byteArray = byteList.ToArray();
//Convert byte-array to image file and return the image
using (MemoryStream stream = new MemoryStream(byteArray))
{
return System.Drawing.Image.FromStream(stream);
}
}
You can use the JSON.NET library to serialize the byte[] into a string which will turn it into hex. Then use the same library to deserialize it back a byte[] when you need to.
I would recommend that you store it as a byte[] in the database though because it will use at least twice the space as a string (one byte in hex is 2 characters, each being a byte at minimum with ASCII or UTF8) and there is a tiny bit of overhead for the JSON format.
Related
I have a jpg image that I can convert into a sequence of binary numbers but I can't recover it afterward. It ends up corrupted.
using System;
using System.IO;
using System.Net.Mime;
using System.Text;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
string inputFilename = "test.jpg";
byte[] fileBytes = File.ReadAllBytes(inputFilename);
var test = ToBinaryString(fileBytes);
byte[] bytes = Encoding.ASCII.GetBytes(test);
string fileresult = Convert.ToBase64String(bytes);
byte[] fileresutl2 = Convert.FromBase64String(fileresult);
File.WriteAllBytes("C:/Users/Florian/RiderProjects/ConsoleApp1/ConsoleApp1/bin/Debug/net5.0/test7.txt", fileresutl2);
string text = System.IO.File.ReadAllText("C:/Users/Florian/RiderProjects/ConsoleApp1/ConsoleApp1/bin/Debug/net5.0/test7.txt");
var result = Convert.ToBase64String(FromBinaryString(text));
File.WriteAllBytes("C:/Users/Florian/RiderProjects/ConsoleApp1/ConsoleApp1/bin/Debug/net5.0/test8.jpg", FromBinaryString(test));
Console.WriteLine(test);
}
public static string ToBinaryString(byte[] array)
{
var s = new StringBuilder();
foreach (byte b in array)
s.Append(Convert.ToString(b, 2));
return s.ToString();
}
public static byte[] FromBinaryString(string s)
{
int count = s.Length / 8;
var b = new byte[count];
for (int i = 0; i < count ; i++)
b[i] = Convert.ToByte(s.Substring(i * 8, 8), 2);
return b;
}
}
}
I don't see what can corrupt my file.
Excuse me for the organization of the file, it is simply a test code coded quickly.
There are some odd things in the code such as uselessly converting to base64 and back, but let's go right to the core of the problem: converting bytes to a binary string
public static string ToBinaryString(byte[] array)
{
var s = new StringBuilder();
foreach (byte b in array)
s.Append(Convert.ToString(b, 2));
return s.ToString();
}
On the face of it, it seems reasonable. Bytes go in, a binary string comes out. But here are some examples that I hope will convince you that there is an issue with this conversion:
Console.WriteLine(ToBinaryString(new byte[]{1, 1}));
Console.WriteLine(ToBinaryString(new byte[]{3}));
( https://ideone.com/y6dB1Z )
These both come out as "11". That's bad, it means the conversion is not reversible. The reason it goes wrong is that the most-significant zeroes are dropped, and then the next byte "shifts into" that position. Every byte should be represented by exactly 8 bits, just as your decoding function expects. For example:
public static string ToBinaryString(byte[] array)
{
var s = new StringBuilder();
foreach (byte b in array)
s.Append(Convert.ToString(b, 2).PadLeft(8, '0'));
return s.ToString();
}
By the way it's not like you should actually ever use something like this (except when experimenting, which it looks like is what you're doing, so it's OK), it inflates the file size by a factor of 8 and doesn't actually do anything useful. If you're going to decode the JPG for example, do that directly with the bytes of the file, not with "the file as a binary string". Even Huffman codes should not be done like that.
I'm writing little decoder. User enter string (hex) that program should decode.
My problem is that int value is not the same as inputed, therefore I don't know how should I advance after reading binary. Am I missing point on how to read binary ?
string input = "0802";
byte[] arr = Encoding.Default.GetBytes(input);
using (MemoryStream stream = new MemoryStream(arr))
{
using (BinaryReader reader = new BinaryReader(stream))
{
int a = reader.ReadInt32();
Console.WriteLine(a);
//output: 842020912
}
}
This is correct. You read 4 bytes from the string so they are interpreted as 4 bytes of your int.
If you check the hex value of your "incorrect" number 842020912 it will give you 0x32303830 and reading every byte as ASCII gives "2080".
The order is reversed as you are reading the value as little-endian.
You are doing it the hard way. I using Bytes but can modify for 1in16, or int32 very easily. :
string input = "0802";
List<byte> bytes = new List<byte>();
for (int i = 0; i < input.Length; i += 2)
{
bytes.Add(byte.Parse(input.Substring(i, 2), System.Globalization.NumberStyles.HexNumber));
}
I am trying to build a larger tool that will take hex strings from .RTF format and dump them to files. This attempt at writing to file from a memory stream is throwing an exception of type 'System.InvalidOperationException' on ReadTimeout and WriteTimeout. I'm a bit in over my head I believe.
the code that I am working with is:
private void button_Click(object sender, RoutedEventArgs e)
{
// Image hex data
string hexImgData = #"FFD8FFE000104A46494600010200006400640000FFFFD9";
// Call function to Convert the hex data to byte array
byte[] newByte = ToByteArray(hexImgData);
MemoryStream memStream = new MemoryStream(newByte);
// Save the memorystream to file
Image image = Image.FromStream(memStream, false, false);
image.Save(#"C:\img.jpg");
memStream.Close();
image.Dispose();
}
// Function converts hex data into byte array
public static byte[] ToByteArray(String HexString)
{
int NumberChars = HexString.Length;
byte[] bytes = new byte[NumberChars / 2];
for (int i = 0; i < NumberChars; i += 2)
{
bytes[i / 2] = Convert.ToByte(HexString.Substring(i, 2), 16);
}
return bytes;
}
}
any help would be appreciated
If all you want to do is take a hex string and dump it to a file, there's no need to overcomplicate it by wrapping it in a MemoryStream and then an Image. Just write the bytes directly to a file:
File.WriteAllBytes(#"C:\img.jpg", newByte);
The reason you get the error is as Ron commented; the hex string you gave does not form a valid JPEG image.
I have the following code:
string s = "2563MNBJP89256666666685755854";
Byte[] bytes = encoding.GetBytes(s);
string hex = "";
foreach (byte b in bytes)
{
int c=b;
hex += String.Format("{0:x2}", (uint)System.Convert.ToUInt32(c.ToString()));
}
It prints the hex values . How can I add it in a vector ob bytes like this?
new byte [0x32,0x35..]
In hex I have : 323536....and so on. The next step is to add then in a byte[] vector in the following format 0x32,0x35..and so on; How to do this?
THX
Isn't bytes already the list of bytes you want?
C#: System.Text.Encoding.ASCII.GetBytes("test")
For C# you could try
System.Text.ASCIIEncoding encoding=new System.Text.ASCIIEncoding();
Byte[] bytes = encoding.GetBytes(strVar);//strVar is the string variable
in C# you can use Encoding.GetBytes Method
string value1 , value1 ;
int length1 , length2 ;
System.Collections.BitArray bitValue1 = new System.Collections.BitArray(Length1);
System.Collections.BitArray bitValue2 = new System.Collections.BitArray(Length2);
I'm looking for the fastest way to covert each string to BitArray with defined length for each string (the string should be trimmed if it is larger than defined length and if strings size is smaller remaining bits will be filled with false) and then put this two strings together and write it in a binary file .
Edit :
#dtb : a simple example can be like this value1 = "A" ,value2 = "B" and length1 =8 and length2 = 16 and the result will be 010000010000000001000010
the first 8 bits are from "A" and next 16 bits from "B"
//Source string
string value1 = "t";
//Length in bits
int length1 = 2;
//Convert the text to an array of ASCII bytes
byte[] bytes = System.Text.Encoding.ASCII.GetBytes(value1);
//Create a temp BitArray from the bytes
System.Collections.BitArray tempBits = new System.Collections.BitArray(bytes);
//Create the output BitArray setting the maximum length
System.Collections.BitArray bitValue1 = new System.Collections.BitArray(length1);
//Loop through the temp array
for(int i=0;i<tempBits.Length;i++)
{
//If we're outside of the range of the output array exit
if (i >= length1) break;
//Otherwise copy the value from the temp to the output
bitValue1.Set(i, tempBits.Get(i));
}
And I'm going to keep saying it, this assumes ASCII characters so anything above ASCII 127 (such as the é in résumé) will freak out and probably return ASCII 63 which is the question mark.
When converting a string to something else you need to consider what encoding you want to use. Here's a version that uses UTF-8
bitValue1 = System.Text.Encoding.UTF8.GetBytes(value1, 0, length1);
Edit
Hmm... saw that you're looking for a BitArray and not a ByteArray, this won't help you probably.
Since this is not a very clear question I'll give this a shot nonetheless,
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
public static void RunSnippet()
{
string s = "123";
byte[] b = System.Text.ASCIIEncoding.ASCII.GetBytes(s);
System.Collections.BitArray bArr = new System.Collections.BitArray(b);
Console.WriteLine("bArr.Count = {0}", bArr.Count);
for(int i = 0; i < bArr.Count; i++)
Console.WriteLin(string.Format("{0}", bArr.Get(i).ToString()));
BinaryFormatter bf = new BinaryFormatter();
using (FileStream fStream = new FileStream("test.bin", System.IO.FileMode.CreateNew)){
bf.Serialize(fStream, (System.Collections.BitArray)bArr);
Console.WriteLine("Serialized to test.bin");
}
Console.ReadLine();
}
Is that what you are trying to achieve?
Hope this helps,
Best regards,
Tom.