C# difference between byte[] and char[] format? - c#

I was wondering those differences, since I have a program that asks me for a byte[].
public static string DecryptTextFromFile(String FileName, byte[] Key, byte[]
IV){}
enter image description here
and I have already tried:
char[] key= { '9', 'D', '2', 'A', 'E'}; doesn't give an error but I need byte[]
and this:
byte[] key= { '9', 'D', '2', 'A', 'E'}; // but this one says that I am using char characters, how do I put them in byte[] format?.

You can initialize a byte array like :
byte[] key1 = new byte[] { 57, 68, 50, 65, 69 };
Or convert from Char Array :
char[] keyChars = { '9', 'D', '2', 'A', 'E' };
var key2 = Encoding.ASCII.GetBytes(keyChars);

The char and byte are two different types, char size is 16 bit and byte size is 8 bit;
To represent a char you need to convert to bytes.
To do that you can use BitConverter
char charValue = 'c';
bytep[] bytes = BitConverter.GetBytes(charValue);
To convert your string from the picture you can use this method
static class HexStringConverter
{
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;
}
}
Hope this answer will help you

Related

Convert a hex string to a byte in C#

I have a String like this:
String data = "0x0f";
and I would like to leave it as a single byte which represents this hex. Does anyone know what function I can use?
I tried using the following function:
public byte pegarValorHexText(string text)
{
int NumberChars = text.Length;
byte[] bytes = new byte[NumberChars / 2];
for (int i = 0; i < NumberChars; i += 2)
bytes[i / 2] = Convert.ToByte(text.Substring(i, 2), 16);
return bytes[0];
}
The string has a hexadecimal value, it has a maximum of 4 characters, the sequence "0x" indicating that it is a hexadecimal value and a sequence of two hex chars
Just use Convert.ToByte then, it should handle the hex prefix:
byte b = Convert.ToByte("0x0f", 16); // 15

Conversion of Hexadecimal to text [duplicate]

I need to check for a string located inside a packet that I receive as byte array. If I use BitConverter.ToString(), I get the bytes as string with dashes (f.e.: 00-50-25-40-A5-FF).
I tried most functions I found after a quick googling, but most of them have input parameter type string and if I call them with the string with dashes, It throws an exception.
I need a function that turns hex(as string or as byte) into the string that represents the hexadecimal value(f.e.: 0x31 = 1). If the input parameter is string, the function should recognize dashes(example "47-61-74-65-77-61-79-53-65-72-76-65-72"), because BitConverter doesn't convert correctly.
Like so?
static void Main()
{
byte[] data = FromHex("47-61-74-65-77-61-79-53-65-72-76-65-72");
string s = Encoding.ASCII.GetString(data); // GatewayServer
}
public static byte[] FromHex(string hex)
{
hex = hex.Replace("-", "");
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;
}
For Unicode support:
public class HexadecimalEncoding
{
public static string ToHexString(string str)
{
var sb = new StringBuilder();
var bytes = Encoding.Unicode.GetBytes(str);
foreach (var t in bytes)
{
sb.Append(t.ToString("X2"));
}
return sb.ToString(); // returns: "48656C6C6F20776F726C64" for "Hello world"
}
public static string FromHexString(string hexString)
{
var bytes = new byte[hexString.Length / 2];
for (var i = 0; i < bytes.Length; i++)
{
bytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16);
}
return Encoding.Unicode.GetString(bytes); // returns: "Hello world" for "48656C6C6F20776F726C64"
}
}
string str = "47-61-74-65-77-61-79-53-65-72-76-65-72";
string[] parts = str.Split('-');
foreach (string val in parts)
{
int x;
if (int.TryParse(val, out x))
{
Console.Write(string.Format("{0:x2} ", x);
}
}
Console.WriteLine();
You can split the string at the -
Convert the text to ints (int.TryParse)
Output the int as a hex string {0:x2}
string hexString = "8E2";
int num = Int32.Parse(hexString, System.Globalization.NumberStyles.HexNumber);
Console.WriteLine(num);
//Output: 2274
From https://msdn.microsoft.com/en-us/library/bb311038.aspx
Your reference to "0x31 = 1" makes me think you're actually trying to convert ASCII values to strings - in which case you should be using something like Encoding.ASCII.GetString(Byte[])
If you need the result as byte array, you should pass it directly without changing it to a string, then change it back to bytes.
In your example the (f.e.: 0x31 = 1) is the ASCII codes. In that case to convert a string (of hex values) to ASCII values use:
Encoding.ASCII.GetString(byte[])
byte[] data = new byte[] { 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30 };
string ascii=Encoding.ASCII.GetString(data);
Console.WriteLine(ascii);
The console will display: 1234567890
My Net 5 solution that also handles null characters at the end:
hex = ConvertFromHex( hex.AsSpan(), Encoding.Default );
static string ConvertFromHex( ReadOnlySpan<char> hexString, Encoding encoding )
{
int realLength = 0;
for ( int i = hexString.Length - 2; i >= 0; i -= 2 )
{
byte b = byte.Parse( hexString.Slice( i, 2 ), NumberStyles.HexNumber, CultureInfo.InvariantCulture );
if ( b != 0 ) //not NULL character
{
realLength = i + 2;
break;
}
}
var bytes = new byte[realLength / 2];
for ( var i = 0; i < bytes.Length; i++ )
{
bytes[i] = byte.Parse( hexString.Slice( i * 2, 2 ), NumberStyles.HexNumber, CultureInfo.InvariantCulture );
}
return encoding.GetString( bytes );
}
One-liners:
var input = "Hallo Hélène and Mr. Hörst";
var ConvertStringToHexString = (string input) => String.Join("", Encoding.UTF8.GetBytes(input).Select(b => $"{b:X2}"));
var ConvertHexToString = (string hexInput) => Encoding.UTF8.GetString(Enumerable.Range(0, hexInput.Length / 2).Select(_ => Convert.ToByte(hexInput.Substring(_ * 2, 2), 16)).ToArray());
Assert.AreEqual(input, ConvertHexToString(ConvertStringToHexString(input)));

Bit convector : Get byte array from string

When I have a string like "0xd8 0xff 0xe0" I do
Text.Split(' ').Select(part => byte.Parse(part, System.Globalization.NumberStyles.HexNumber)).ToArray();
But if I got string like "0xd8ffe0" I don't know what to do ?
also I'm able for recommendations how to write byte array as one string.
You need to scrub your string before you start parsing it. First, remove the leading 0x, then just skip any spaces as you enumerate the string. But using LINQ for this is probably not the best approach. For one, the code won't be very readable and it'll be hard to step through if you're debugging. But also, there are some tricks you can do to make hex/byte conversions very fast. For example, don't use Byte.Parse, but instead use array indexing to "look up" the corresponding value.
A while back I implemented a HexEncoding class that derives from the Encoding base class much like ASCIIEncoding and UTF8Encoding, etc. Using it is very simple. It's pretty well optimized too which can be very important depending on the size of your data.
var enc = new HexEncoding();
byte[] bytes = enc.GetBytes(str); // convert hex string to byte[]
str = enc.GetString(bytes); // convert byte[] to hex string
Here's the complete class, I know it's kinda big for a post but I've stripped out the doc comments.
public sealed class HexEncoding : Encoding
{
public static readonly HexEncoding Hex = new HexEncoding( );
private static readonly char[] HexAlphabet;
private static readonly byte[] HexValues;
static HexEncoding( )
{
HexAlphabet = new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
HexValues = new byte[255];
for ( int i = 0 ; i < HexValues.Length ; i++ ) {
char c = (char)i;
if ( "0123456789abcdefABCDEF".IndexOf( c ) > -1 ) {
HexValues[i] = System.Convert.ToByte( c.ToString( ), 16 );
} // if
} // for
}
public override string EncodingName
{
get
{
return "Hex";
}
}
public override bool IsSingleByte
{
get
{
return true;
}
}
public override int GetByteCount( char[] chars, int index, int count )
{
return count / 2;
}
public override int GetBytes( char[] chars, int charIndex, int charCount, byte[] bytes, int byteIndex )
{
int ci = charIndex;
int bi = byteIndex;
while ( ci < ( charIndex + charCount ) ) {
char c1 = chars[ci++];
char c2 = chars[ci++];
byte b1 = HexValues[(int)c1];
byte b2 = HexValues[(int)c2];
bytes[bi++] = (byte)( b1 << 4 | b2 );
} // while
return charCount / 2;
}
public override int GetCharCount( byte[] bytes, int index, int count )
{
return count * 2;
}
public override int GetChars( byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex )
{
int ci = charIndex;
int bi = byteIndex;
while ( bi < ( byteIndex + byteCount ) ) {
int b1 = bytes[bi] >> 4;
int b2 = bytes[bi++] & 0xF;
char c1 = HexAlphabet[b1];
char c2 = HexAlphabet[b2];
chars[ci++] = c1;
chars[ci++] = c2;
} // while
return byteCount * 2;
}
public override int GetMaxByteCount( int charCount )
{
return charCount / 2;
}
public override int GetMaxCharCount( int byteCount )
{
return byteCount * 2;
}
} // class
Hex String to byte[]:
byte[] bytes = new byte[value.Length / 2];
for (int i = 0; i < value.Length; i += 2)
{
bytes[i / 2] = Convert.ToByte(value.Substring(i, 2), 16);
}
If you have "0x" at the beginning you should skip two bytes.
byte[] or any IEnumerable<Byte> -> Hex String:
return sequence.Aggregate(string.Empty,
(result, value) => result +
string.Format(CultureInfo.InvariantCulture, "{0:x2}", value));

C# SHA-1 vs. PHP SHA-1...Different Results?

I am trying to calculate a SHA-1 Hash from a string, but when I calculate the string using php's sha1 function I get something different than when I try it in C#. I need C# to calculate the same string as PHP (since the string from php is calculated by a 3rd party that I cannot modify). How can I get C# to generate the same hash as PHP? Thanks!!!
String = s934kladfklada#a.com
C# Code (Generates d32954053ee93985f5c3ca2583145668bb7ade86)
string encode = secretkey + email;
UnicodeEncoding UE = new UnicodeEncoding();
byte[] HashValue, MessageBytes = UE.GetBytes(encode);
SHA1Managed SHhash = new SHA1Managed();
string strHex = "";
HashValue = SHhash.ComputeHash(MessageBytes);
foreach(byte b in HashValue) {
strHex += String.Format("{0:x2}", b);
}
PHP Code (Generates a9410edeaf75222d7b576c1b23ca0a9af0dffa98)
sha1();
Use ASCIIEncoding instead of UnicodeEncoding. PHP uses ASCII charset for hash calculations.
This method in .NET is equivalent to sha1 in php:
string sha1Hash(string password)
{
return string.Join("", SHA1CryptoServiceProvider.Create().ComputeHash(Encoding.UTF8.GetBytes(password)).Select(x => x.ToString("x2")));
}
I had this problem also. The following code will work.
string dataString = "string to hash";
SHA1 hash = SHA1CryptoServiceProvider.Create();
byte[] plainTextBytes = Encoding.ASCII.GetBytes(dataString);
byte[] hashBytes = hash.ComputeHash(plainTextBytes);
string localChecksum = BitConverter.ToString(hashBytes)
.Replace("-", "").ToLowerInvariant();
Had the same problem. This code worked for me:
string encode = secretkey + email;
SHA1 sha1 = SHA1CryptoServiceProvider.Create();
byte[] encodeBytes = Encoding.ASCII.GetBytes(encode);
byte[] encodeHashedBytes = sha1.ComputeHash(passwordBytes);
string pencodeHashed = BitConverter.
ToString(encode HashedBytes).Replace("-", "").ToLowerInvariant();
FWIW, I had a similar issue in Java. It turned out that I had to use "UTF-8" encoding to produce the same SHA1 hashes in Java as the sha1 function produces in PHP 5.3.1 (running on XAMPP Vista).
private static String SHA1(final String text) throws NoSuchAlgorithmException, UnsupportedEncodingException {
final MessageDigest md = MessageDigest.getInstance("SHA-1");
md.update(text.getBytes("UTF-8"));
return new String(org.apache.commons.codec.binary.Hex.encodeHex(md.digest()));
}
Try The following! I think it will work great:
public static string SHA1Encodeb64(string toEncrypt)
{
//Produce an array of bytes which is the SHA1 hash
byte[] sha1Signature = new byte[40];
byte[] sha = System.Text.Encoding.Default.GetBytes(toEncrypt);
SHA1 sha1 = SHA1Managed.Create();
sha1Signature = sha1.ComputeHash(sha);
/**
* The BASE64 encoding standard's 6-bit alphabet, from RFC 1521,
* plus the padding character at the end.
*/
char[] Base64Chars = {
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
'w', 'x', 'y', 'z', '0', '1', '2', '3',
'4', '5', '6', '7', '8', '9', '+', '/',
'='
};
//Algorithm to encode the SHA1 hash using Base64
StringBuilder sb = new StringBuilder();
int len = sha1Signature.Length;
int i = 0;
int ival;
while (len >= 3)
{
ival = ((int)sha1Signature[i++] + 256) & 0xff;
ival <<= 8;
ival += ((int)sha1Signature[i++] + 256) & 0xff;
ival <<= 8;
ival += ((int)sha1Signature[i++] + 256) & 0xff;
len -= 3;
sb.Append(Base64Chars[(ival >> 18) & 63]);
sb.Append(Base64Chars[(ival >> 12) & 63]);
sb.Append(Base64Chars[(ival >> 6) & 63]);
sb.Append(Base64Chars[ival & 63]);
}
switch (len)
{
case 0: // No pads needed.
break;
case 1: // Two more output bytes and two pads.
ival = ((int)sha1Signature[i++] + 256) & 0xff;
ival <<= 16;
sb.Append(Base64Chars[(ival >> 18) & 63]);
sb.Append(Base64Chars[(ival >> 12) & 63]);
sb.Append(Base64Chars[64]);
sb.Append(Base64Chars[64]);
break;
case 2: // Three more output bytes and one pad.
ival = ((int)sha1Signature[i++] + 256) & 0xff;
ival <<= 8;
ival += ((int)sha1Signature[i] + 256) & 0xff;
ival <<= 8;
sb.Append(Base64Chars[(ival >> 18) & 63]);
sb.Append(Base64Chars[(ival >> 12) & 63]);
sb.Append(Base64Chars[(ival >> 6) & 63]);
sb.Append(Base64Chars[64]);
break;
}
//Encode the signature using Base64
string base64Sha1Signature = sb.ToString();
return base64Sha1Signature;
}

Converting from hex to string

I need to check for a string located inside a packet that I receive as byte array. If I use BitConverter.ToString(), I get the bytes as string with dashes (f.e.: 00-50-25-40-A5-FF).
I tried most functions I found after a quick googling, but most of them have input parameter type string and if I call them with the string with dashes, It throws an exception.
I need a function that turns hex(as string or as byte) into the string that represents the hexadecimal value(f.e.: 0x31 = 1). If the input parameter is string, the function should recognize dashes(example "47-61-74-65-77-61-79-53-65-72-76-65-72"), because BitConverter doesn't convert correctly.
Like so?
static void Main()
{
byte[] data = FromHex("47-61-74-65-77-61-79-53-65-72-76-65-72");
string s = Encoding.ASCII.GetString(data); // GatewayServer
}
public static byte[] FromHex(string hex)
{
hex = hex.Replace("-", "");
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;
}
For Unicode support:
public class HexadecimalEncoding
{
public static string ToHexString(string str)
{
var sb = new StringBuilder();
var bytes = Encoding.Unicode.GetBytes(str);
foreach (var t in bytes)
{
sb.Append(t.ToString("X2"));
}
return sb.ToString(); // returns: "48656C6C6F20776F726C64" for "Hello world"
}
public static string FromHexString(string hexString)
{
var bytes = new byte[hexString.Length / 2];
for (var i = 0; i < bytes.Length; i++)
{
bytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16);
}
return Encoding.Unicode.GetString(bytes); // returns: "Hello world" for "48656C6C6F20776F726C64"
}
}
string str = "47-61-74-65-77-61-79-53-65-72-76-65-72";
string[] parts = str.Split('-');
foreach (string val in parts)
{
int x;
if (int.TryParse(val, out x))
{
Console.Write(string.Format("{0:x2} ", x);
}
}
Console.WriteLine();
You can split the string at the -
Convert the text to ints (int.TryParse)
Output the int as a hex string {0:x2}
string hexString = "8E2";
int num = Int32.Parse(hexString, System.Globalization.NumberStyles.HexNumber);
Console.WriteLine(num);
//Output: 2274
From https://msdn.microsoft.com/en-us/library/bb311038.aspx
Your reference to "0x31 = 1" makes me think you're actually trying to convert ASCII values to strings - in which case you should be using something like Encoding.ASCII.GetString(Byte[])
If you need the result as byte array, you should pass it directly without changing it to a string, then change it back to bytes.
In your example the (f.e.: 0x31 = 1) is the ASCII codes. In that case to convert a string (of hex values) to ASCII values use:
Encoding.ASCII.GetString(byte[])
byte[] data = new byte[] { 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30 };
string ascii=Encoding.ASCII.GetString(data);
Console.WriteLine(ascii);
The console will display: 1234567890
My Net 5 solution that also handles null characters at the end:
hex = ConvertFromHex( hex.AsSpan(), Encoding.Default );
static string ConvertFromHex( ReadOnlySpan<char> hexString, Encoding encoding )
{
int realLength = 0;
for ( int i = hexString.Length - 2; i >= 0; i -= 2 )
{
byte b = byte.Parse( hexString.Slice( i, 2 ), NumberStyles.HexNumber, CultureInfo.InvariantCulture );
if ( b != 0 ) //not NULL character
{
realLength = i + 2;
break;
}
}
var bytes = new byte[realLength / 2];
for ( var i = 0; i < bytes.Length; i++ )
{
bytes[i] = byte.Parse( hexString.Slice( i * 2, 2 ), NumberStyles.HexNumber, CultureInfo.InvariantCulture );
}
return encoding.GetString( bytes );
}
One-liners:
var input = "Hallo Hélène and Mr. Hörst";
var ConvertStringToHexString = (string input) => String.Join("", Encoding.UTF8.GetBytes(input).Select(b => $"{b:X2}"));
var ConvertHexToString = (string hexInput) => Encoding.UTF8.GetString(Enumerable.Range(0, hexInput.Length / 2).Select(_ => Convert.ToByte(hexInput.Substring(_ * 2, 2), 16)).ToArray());
Assert.AreEqual(input, ConvertHexToString(ConvertStringToHexString(input)));

Categories

Resources