I have a string array that contains some binary data, and I would like to convert the binary to its equivalent character representative.
Each element inside the array contains 8 bit "1 byte" of data and I need to know how to convert it to its character equivalence
Here is the string array:
IEnumerable<string> resultChunks = Enumerable.Range(0, result.Length / 8)
.Select(x => result.Substring(x * 8, 8));
string[] newRes = resultChunks.ToArray();
string tempRes="";
for (int i = 0; i < newRes.Length; i++)
{
tempRes+=Convert.ToString(newRes[i]);
}
Current "result" is "0010001111000100001010010011101111000111001100110110011100110110"
If your data is in a byte array then you could use this:
string result = Encoding.ASCII.GetString(bytes);
I guess, your string is base64 string.
Then you can use next method:
public static string FromBase64(string base64Str, Encoding encoding = null)
{
if (string.IsNullOrWhiteSpace(base64Str))
{
return string.Empty;
}
byte[] bytes;
try
{
bytes = System.Convert.FromBase64String(base64Str);
}
catch (FormatException)
{
return string.Empty;
}
var stringEncoding = encoding ?? Encoding.UTF8;
return stringEncoding.GetString(bytes);
}
Related
I have json string as in example below
{"SaleToPOIRequest":{"MessageHeader":{"ProtocolVersion":"2.0","MessageClass":"Service","MessageCategory":"Login","MessageType":"Request","ServiceID":"498","SaleID":"SaleTermA","POIID":"POITerm1"},"LogoutRequest":{}}}
I want to convert json request to hexadecimal. I tried example in this link but i cannot get the exact conversion because of {,:,",} values.
Actually i can get hexadecimal return but when i reconvert to string i got return as below
{"SaleToPOIReque§7B#§²$ÖW76vTVder":{"ProtocolV¦W'6öâ#¢#"ã"Â$ÚessageClass":"Se§'f6R"Â$ÖW76vT:ategory":"Login"¢Â$ÖW76vUGR#¢*Request","Servic¤B#¢#C"Â%6ÆZID":"SaleTermA",¢%ôB#¢%ôFW&Ú1"},"LogoutReque§7B#§·×
that is not usefull for me
Is there any way to convert this?
So basically the problem is not only converting to hex but also converting back.
This is nothing more then combining 2 answers already on SO:
First for converting we use the answer given here: Convert string to hex-string in C#
Then for the converting back you can use this answer:
https://stackoverflow.com/a/724905/10608418
For you it would then look something like this:
class Program
{
static void Main(string[] args)
{
var input = "{\"SaleToPOIRequest\":{\"MessageHeader\":{\"ProtocolVersion\":\"2.0\",\"MessageClass\":\"Service\",\"MessageCategory\":\"Login\",\"MessageType\":\"Request\",\"ServiceID\":\"498\",\"SaleID\":\"SaleTermA\",\"POIID\":\"POITerm1\"},\"LogoutRequest\":{}}}";
var hex = string.Join("",
input.Select(c => String.Format("{0:X2}", Convert.ToInt32(c))));
var output = Encoding.ASCII.GetString(FromHex(hex));
Console.WriteLine($"input: {input}");
Console.WriteLine($"hex: {hex}");
Console.WriteLine($"output: {output}");
Console.ReadKey();
}
public static byte[] FromHex(string hex)
{
byte[] raw = new byte[hex.Length / 2];
for (int i = 0; i < raw.Length; i++)
{
raw[i] = Convert.ToByte(hex.Substring(i * 2, 2), 16);
}
return raw;
}
}
See it in action in a fiddle here:
https://dotnetfiddle.net/axUC5n
Hope this helps and good luck with your project
You should most probably use Encoding.Unicode to convert the string to a byte array: it's quite possible that some characters cannot be represented by ASCII chars.
Encoding.Unicode (UTF-16LE) always uses 2 bytes, so it's predictable: a sequence of 4 chars in the HEX string will always represent an UFT-16 CodePoint.
No matter what characters the input string contains.
Convert string to HEX:
string input = "Yourstring \"Ваша строка\"{あなたのひも},آپ کی تار";;
string hex = string.Concat(Encoding.Unicode.GetBytes(input).Select(b => b.ToString("X2")));
Convert back to string:
var bytes = new List<byte>();
for (int i = 0; i < hex.Length; i += 2) {
bytes.Add(byte.Parse(hex.Substring(i, 2), NumberStyles.HexNumber));
}
string original = Encoding.Unicode.GetString(bytes.ToArray());
How do I further encrypt a MD5 hash by XOR'ing it with a string of variable size (not bigger than 32 characters) ?
I would like the result of the XOR to be a 32 character string as well.
What i have tried so far is:
convert the md5 string to binary
convert second string to binary
pad second binary with 0's (to the left) until both binaries are of equal length
iterate the binary representations and XOR them
convert the XOR'ed result to a string
The approach may be wrong, im not sure how to do it. My problem is, when converting the result of the XOR, it is not a 32 character long string, as I would like it to be.
Sample code (equal length strings in this case):
class Program
{
static void Main(string[] args)
{
var md51 = ToBinary(ConvertToByteArray(CalculateMD5Hash("Maaa"), Encoding.ASCII));
var md52 = ToBinary(ConvertToByteArray(CalculateMD5Hash("Moo"), Encoding.ASCII));
List<int> xoredResult = new List<int>();
for (int i = 0; i < md51.Length; i++)
{
var string1 = md51[i];
var string2 = md52[i];
var xor = string1 ^ string2;
xoredResult.Add(xor);
}
var resultingString = string.Join("", xoredResult);
Console.WriteLine(resultingString.Length);
var data = GetBytesFromBinaryString(resultingString);
var text = Encoding.ASCII.GetString(data);
}
public static byte[] ConvertToByteArray(string str, Encoding encoding)
{
return encoding.GetBytes(str);
}
public static String ToBinary(Byte[] data)
{
return string.Join("", data.Select(byt => Convert.ToString(byt, 2).PadLeft(8, '0')));
}
public static Byte[] GetBytesFromBinaryString(String binary)
{
var list = new List<Byte>();
for (int i = 0; i < binary.Length; i += 8)
{
String t = binary.Substring(i, 8);
list.Add(Convert.ToByte(t, 2));
}
return list.ToArray();
}
public static string CalculateMD5Hash(string input)
{
// step 1, calculate MD5 hash from input
MD5 md5 = System.Security.Cryptography.MD5.Create();
byte[] inputBytes = System.Text.Encoding.ASCII.GetBytes(input);
byte[] hash = md5.ComputeHash(inputBytes);
// step 2, convert byte array to hex string
StringBuilder sb = new StringBuilder();
for (int i = 0; i < hash.Length; i++)
{
sb.Append(hash[i].ToString("X2"));
}
return sb.ToString();
}
}
xoring a string with what is essentially random bytes is not guaranteed to give you a valid string as a output. Your var text = Encoding.ASCII.GetString(data); is likely failing because you are passing it a non valid string in byte form. You must use something like var text = Convert.ToBase64String(data) to be able to represent the random data without loss of information in the process.
I have a random integer value which I need to represent in String as a Byte array. For example:
int value = 32;
String strValue = getStringByteArray(value);
Console.WriteLine(strValue); // should write: " \0\0\0"
If value = 11 then getStringByteArray(value) shuld return "\v\0\0\0".
If value = 13 then getStringByteArray(value) shuld return "\r\0\0\0".
And so on.
Any idea on how to implement the method getStringByteArray(int value) in C#?
UPDATE
This is the code that receives the data from the C# NamedPipe Server:
bool CFilePipe::ReadString(int m_handle, string &value)
{
//--- check for data
if(WaitForRead(sizeof(int)))
{
ResetLastError();
int size=FileReadInteger(m_handle);
if(GetLastError()==0)
{
//--- check for data
if(WaitForRead(size))
{
value=FileReadString(m_handle,size);
return(size==StringLen(value));
}
}
}
//--- failure
return(false);
}
Don't take this approach at all. You should be writing to a binary stream of some description - and write the binary data for the length of the packet/message, followed by the message itself. For example:
BinaryWriter writer = new BinaryWriter(stream);
byte[] data = Encoding.UTF8.GetBytes(text);
writer.Write(data.Length);
writer.Write(data);
Then at the other end, you'd use:
BinaryReader reader = new BinaryReader(stream);
int length = reader.ReadInt32();
byte[] data = reader.ReadBytes(length);
string text = Encoding.UTF8.GetString(data);
No need to treat binary data as text at all.
Well. First of all you should get bytes from integer. You can do it with BitConverter:
var bytes = BitConverter.GetBytes(value);
Next, here is three variants. First - if you want to get result in binary format. Just take all your bytes and write as it is:
var str = string.Concat(bytes.Select(b => Convert.ToString(b, 2)));
Second variant. If you want convert your byte array to hexadecimal string:
var hex = BitConverter.ToString(array).Replace("-","");
Third variant. Your representation ("\v\0\0\0") - it is simple converting byte to char. Use this:
var s = bytes.Aggregate(string.Empty, (current, t) => current + Convert.ToChar(t));
This should help with that.
class Program
{
static void Main(string[] args)
{
Random rand = new Random();
int number = rand.Next(1, 1000);
byte[] intBytes = BitConverter.GetBytes(number);
string answer = "";
for (int i = 0; i < intBytes.Length; i++)
{
answer += intBytes[i] + #"\";
}
Console.WriteLine(answer);
Console.WriteLine(number);
Console.ReadKey();
}
}
Obviously, you should implement two steps to achieve the goal:
Extract bytes from the integer in the appropriate order (little-endian or big-endian, it's up to you to decide), using bit arithmetics.
Merge extracted bytes into string using the format you need.
Possible implementation:
using System;
using System.Text;
public class Test
{
public static void Main()
{
Int32 value = 5152;
byte[] bytes = new byte[4];
for (int i = 0; i < 4; i++)
{
bytes[i] = (byte)((value >> i * 8) & 0xFF);
}
StringBuilder result = new StringBuilder();
for (int i = 0; i < 4; i++)
{
result.Append("\\" + bytes[i].ToString("X2"));
}
Console.WriteLine(result);
}
}
Ideone snippet: http://ideone.com/wLloo1
I think you are saying that you want to convert each byte into a character literal, using escape sequences for the non printable characters.
After converting the integer to 4 bytes, cast to char. Then use Char.IsControl() to identify the non-printing characters. Use the printable char directly, and use a lookup table to find the corresponding escape sequence for each non-printable char.
I'm downloading HTML file with polish characters, and parsing it to string by:
public static string HexToString(string hex)
{
var sb = new StringBuilder();
for (int i = 0; i < hex.Length; i += 2)
{
string hexdec = hex.Substring(i, 2);
int number = int.Parse(hexdec, NumberStyles.HexNumber);
char charToAdd = (char)number;
sb.Append(charToAdd);
}
return sb.ToString();
}
so when I found %21 I'm sending 21 to HexToString() and in return there is !, this is ok, but char ą is represented as %C4%85 (Ä) and I whant to get ą char
The problem here is that you are treating the hex codes as if they are UTF16 (which is the native format for char), but they are in fact UTF8.
This is easy to resolve using a UTF8 encoding.
First, let's write a handy StringToByteArray() method:
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();
}
Now you can convert the hex string to text like so:
string hexStr = "C485"; // Or whatever your input hex string is.
var bytes = StringToByteArray(hexStr);
string text = Encoding.UTF8.GetString(bytes);
// ...use text
Matthew is right, but you can also use this:
public static string ConvertHexToString(string HexValue)
{
var res = "";
var replacedHex = HexValue.Replace("%", String.Empty);
while (replacedHex.Length > 0)
{
res += System.Convert.ToChar(System.Convert.ToUInt32(replacedHex.Substring(0, 2), 16)).ToString();
replacedHex = replacedHex.Substring(2, replacedHex.Length - 2);
}
return res;
}
I am converting two properties string TokenValue and TokenType which is enum TokenType : byte I am able to convert to a byte array using the below method and separating the two properties with a %.
public byte[] ToByteArray()
{
List<Byte> bytes = new List<byte>();
bytes.AddRange(Encoding.ASCII.GetBytes(TokenValue));
bytes.AddRange(Encoding.ASCII.GetBytes("%"));
bytes.Add((byte)this.TokenType);
return bytes.ToArray();
}
My problem is trying to convert back using:
public void FromByteArray(byte[] value)
{
Regex reg = new Regex("%");
string str = Encoding.UTF8.GetString(value);
string[] fields = reg.Split(str);
if (fields.Count() > 1)
{
TokenValue = fields[0];
TokenType = (TokenType)Encoding.ASCII.GetBytes(fields[1]); //Something along these lines to convert back to the TokenType
}
else if (fields.Count() == 1)
{
TokenValue = fields[0];
}
}
Not sure how to convert the bytes back to the enum TokenType
Thanks in advance.
In ToByteArray() you convert everything to bytes and then concatenate the byte values. Therefore, in FromByteArray(), you need to split the byte array before you decode it into strings etc:
public void FromByteArray(byte[] value)
{
var delimiter = (byte)'%';
var stringBytes = value.TakeWhile(b => b != delimiter).ToArray();
var enumByte = 0;
if (stringBytes.Length < value.Length)
{
enumByte = value.Last();
}
TokenValue = Encoding.ASCII.GetString(stringBytes);
TokenType = (TokenType)enumByte;
}