Replace Hex String in File - c#

After banging my head on it for hours, I am at my wits end. I have a hex string in a file that is "68 39 30 00 00". The "39 30" is the decimal value "12345" which I am wanting to replace, and the "68" and "00 00" are just to ensure there is a single match.
I want to pass in a new decimal value such as "12346", and replace the existing value in the file. I have tried converting everything back and fourth between hex, byte arrays, and so on and feel it has to be much simpler than I am making it out to be.
static void Main(string[] args)
{
// Original Byte string to find and Replace "12345"
byte[] original = new byte[] { 68, 39, 30, 00, 00 };
int newPort = Convert.ToInt32("12346");
string hexValue = newPort.ToString("X2");
byte[] byteValue = StringToByteArray(hexValue);
// Build Byte Array of the port to replace with. Starts with /x68 and ends with /x00/x00
byte[] preByte = new byte[] { byte.Parse("68", System.Globalization.NumberStyles.HexNumber) };
byte[] portByte = byteValue;
byte[] endByte = new byte[] { byte.Parse("00", System.Globalization.NumberStyles.HexNumber), byte.Parse("00", System.Globalization.NumberStyles.HexNumber) };
byte[] replace = new byte[preByte.Length + portByte.Length + endByte.Length];
preByte.CopyTo(replace, 0);
portByte.CopyTo(replace, preByte.Length);
endByte.CopyTo(replace, (preByte.Length + portByte.Length));
Patch("Server.exe", "Server1.exe", original, replace);
}
static private 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();
}

The decimal value of 39 30 is 14640 so it will check for the 14640 which is not present.
Hex value for 12345 is 30 39. Just correct the values and your program will work fine.

Related

byte[] with ASCII values to string to int

So someone took int value, converted it to string then converted it to ASCII values and then finally to byte[] with inconsistent length 1 - 4 bytes.
e.g. 100 -> "100" -> { 49, 48, 48 }.
Now I need that int value and I did it like this:
{ 49, 48, 48 } -> '1' + '0' + '0' -> "100" -> 100
switch (header[25].Count)
{
case 1:
hex = "" + (char)header[25][0];
amountOfData = Convert.ToInt32(hex, 16);
break;
case 2:
hex = "" + (char)header[25][0] + (char)header[25][1];
amountOfData = Convert.ToInt32(hex, 16);
break;
case 3:
hex = "" + (char)header[25][0] + (char)header[25][1] + (char)header[25][2];
amountOfData = Convert.ToInt32(hex, 16);
break;
case 4:
hex = "" + (char)header[25][0] + (char)header[25][1] + (char)header[25][2] + (char)header[25][3];
amountOfData = Convert.ToInt32(hex, 16); ;
break;
default:
break;
}
but maybe there is better solution...
EDIT: sorry for not mentioning that, but header is List<List<byte>>
You can use the Encoding/GetString method to convert bytes of different encodings (e.g. ASCII in your case) to a .NET string:
var input = new byte[] { 49, 48, 48 };
var str = Encoding.ASCII.GetString(input);
var result = int.Parse(str, NumberStyles.None, CultureInfo.InvariantCulture);
You can use library functions to parse from byte-like data to primitives; you're talking about ASCII, which means that Utf8Parser will work fine for us (all ASCII is also valid UTF8, although the reverse is obviously not true); normally, we would expect that header[25] is a byte[], a segment there-of, or some other raw binary source, but: ultimately, something like:
var span = new ReadOnlySpan<byte>(header[25], 0, header[25].Count);
if (!Utf8Parser.TryParse(span, out int amountOfData, out _))
ThrowSomeError(); // not an integer
If header[25] is something less convenient (like a List<byte> - I notice that in your example, your header[25] has a .Count not a .Length, which suggests it isn't a byte[]), then you can always either stackalloc a local buffer and copy the data out, or you can peek inside the list with CollectionMarshal.AsSpan<T>(List<T>), which returns a Span<T> from the underlying data:
var span = CollectionMarshal.AsSpan(header[25]);
if (!Utf8Parser.TryParse(span, out int amountOfData, out _))
ThrowSomeError(); // not an integer
As a runnable example that just shows the API:
using System;
using System.Buffers.Text;
Span<byte> span = stackalloc byte[] { 49, 48, 48 };
if (!Utf8Parser.TryParse(span, out int amountOfData, out _))
throw new FormatException();
Console.WriteLine(amountOfData); // 100

How to convert byte array to binary values and then write it in a comma separated text file

I have a byte array:
newMsg.DATA = new byte[64];
How can I convert it into binary value and then write it in text file with comma separation. Comma should be in between binary values not bytes.....
like 1,1,1,0,0,0,1,1,1,1,1,0,0,0,0,0.......
Here is an example that uses LINQ:
byte[] arr = new byte[] { 11, 55, 255, 188, 99, 22, 31, 43, 25, 122 };
string[] result = arr.Select(x => string.Join(",", Convert.ToString(x, 2)
.PadLeft(8, '0').ToCharArray())).ToArray();
System.IO.File.WriteAllLines(#"D:\myFile.txt", result);
Every number in byte[] arr is converted to a binary number with Convert.ToString(x, 2) and the comma "," is added between binary values with string.Join(",",...). At the end you can write all the elements in result to a text file by using System.IO.File.WriteAllLines.
The example above gives you this kind of output in a txt file:
0,0,0,0,1,0,1,1
0,0,1,1,0,1,1,1
1,1,1,1,1,1,1,1
...
Explanation of Convert.ToString(value, baseValue):
The first parameter value represents the number you want to convert to a string
and the second parameter baseValue represents which type of conversion you want to perform.
Posible baseValues are : 2,8,10 and 16.
BaseValue = 2 - represents a conversion to a binary number representation.
BaseValue = 8 - represents a conversion to a octal number representation.
BaseValue = 10 - represents a conversion to a decimal number representation.
BaseValue = 16 - represents a conversion to a hexadecimal number representation.
I think this will Help you c# provides inbuilt functionality to do so
with help of Convert.ToString(byte[],base); here base could be[2(binary),8(octal),16(HexaDecimal)]
byte[] data = new byte[64];
// 2nd parameter 2 is Base e.g.(binary)
string a = Convert.ToString(data[data.Length], 2);
StringBuilder sb = new StringBuilder();
foreach(char ch in a.ToCharArray())
{
sb.Append(ch+",");
}
// This is to remove last extra ,
string ans = sb.ToString().Remove(sb.Length - 1, 1);
This should get you going:
var bytes = new byte[] { 128, 255, 2 };
var stringBuilder = new StringBuilder();
for (var index = 0; index < bytes.Length; index++)
{
var binary = Convert.ToString(bytes[index], 2).PadLeft(8, '0');
var str = string.Join(",", binary.ToCharArray());
stringBuilder.Append(str);
if (index != bytes.Length -1) stringBuilder.Append(",");
}
Console.WriteLine(stringBuilder);

Byte arrays to base64 string

Say I have two byte arrays.
In the first scenario, I concatenate the two arrays (using Buffer.BlockCopy), then convert the result to base64 string.
In the second scenario, I convert each byte array into base64 string and then concatenate those strings.
Would the two results be the same?
Results would be the same if length of the first array is divisible by 3, in all other cases result of concatenation of two base64 strings would be different (and invalid base64) due to padding bytes at the end of first string. Length of second array does not matter for this operation as padding is always at the end.
Why "divisible by 3" - since base64 encodes every 3 bytes into exactly 4 characters arrays of such length will not need padding at the end. See https://www.rfc-editor.org/rfc/rfc4648#section-4 for formal details and https://en.wikipedia.org/wiki/Base64#Padding for more readable explanation.
I.e. if first array is 4 bytes long you get == at the end of converted string and concatenation with other base64 string will result in invalid base64 text
Convert.ToBase64String(new byte[]{1,2,3,4}) // AQIDBA==
Sample case where concatenation works the same on arrays first or on strings:
Convert.ToBase64String(new byte[]{1,2,3}) + // length divisible by 3
Convert.ToBase64String(new byte[]{4,5})
==
Convert.ToBase64String(new byte[]{1,2,3,4,5}) // AQIDBAU=
void Main()
{
byte[] bytes1 = new byte[]{10, 20, 30, 40, 0, 0, 0, 0};
byte[] bytes2 = new byte[]{50, 60, 70, 80};
Buffer.BlockCopy(bytes2, 0, bytes1, 4, 4);
PrintByteArray(bytes1);
string bytesStr = Convert.ToBase64String(bytes1);
Console.WriteLine(bytesStr);
string bytesStr1 = Convert.ToBase64String(bytes1);
string bytesStr2 = Convert.ToBase64String(bytes2);
string bytesStrMerged = bytesStr1 + bytesStr2;
Console.WriteLine(bytesStrMerged);
}
public void PrintByteArray(byte[] bytes)
{
var sb = new StringBuilder();
foreach (var b in bytes)
{
sb.Append(b + " ");
}
Console.WriteLine(sb.ToString());
}
Outputs:
10 20 30 40 50 60 70 80
ChQeKDI8RlA=
ChQeKDI8RlA=MjxGUA==

Decrypt string using Bouncy Castle RC4 algorithm in C#

I am trying to use library Bouncy Castle for decrypting. But the decrypted string is not correct. I am getting value Aa1ŽYY445Ló, but correct value should be Aa11YY445LL. What I am doing wrong? When I try to decrypt string on http://rc4.online-domain-tools.com/ I am getting correct result.
Code sample:
string textToDecrypt = HexDumper.FromHex("E5497380DC724B28284D80");
var key = Encoding.UTF8.GetBytes("heslo");
var cipher = new RC4Engine();
cipher.Init(true, new KeyParameter(key));
byte[] inBytes = UTF8Encoding.GetEncoding(1252).GetBytes(textToDecrypt);
byte[] outBuffer = new byte[1024 * 4];
cipher.ProcessBytes(inBytes, 0, inBytes.Length, outBuffer, 0);
// Output must be 41 61 31 31 59 59 34 34 35 4c 4c -> Aa11YY445LL
var textDecrypted = ASCIIEncoding.GetEncoding(1252).GetString(outBuffer);
int indexOf0 = textDecrypted.IndexOf("\0");
if (indexOf0 > 0)
{
textDecrypted = textDecrypted.Substring(0, indexOf0);
MessageBox.Show(textDecrypted);
}
public static string FromHex(string hexString)
{
string StrValue = "";
while (hexString.Length > 0)
{
StrValue += System.Convert.ToChar(System.Convert.ToUInt32(hexString.Substring(0, 2), 16)).ToString();
hexString = hexString.Substring(2, hexString.Length - 2);
}
return StrValue;
}
The problem is your FromHex function.
Swapped it with the top answer from How can I convert a hex string to a byte array? and got the correct result.
Not sure specifically what's wrong (in terms of functionality) with your FromHex, though -- you should probably figure that out.

How to convert decimal string value to hex byte array in C#?

I have an input string which is in decimal format:
var decString = "12345678"; // in hex this is 0xBC614E
and I want to convert this to a fixed length hex byte array:
byte hexBytes[] // = { 0x00, 0x00, 0xBC, 0x61, 0x4E }
I've come up with a few rather convoluted ways to do this but I suspect there is a neat two-liner! Any thoughts? Thanks
UPDATE:
OK I think I may have inadvertently added a level of complexity by having the example showing 5 bytes. Maximum is in fact 4 bytes (FF FF FF FF) = 4294967295. Int64 is fine.
If you have no particular limit to the size of your integer, you could use BigInteger to do this conversion:
var b = BigInteger.Parse("12345678");
var bb = b.ToByteArray();
foreach (var s in bb) {
Console.Write("{0:x} ", s);
}
This prints
4e 61 bc 0
If the order of bytes matters, you may need to reverse the array of bytes.
Maximum is in fact 4 bytes (FF FF FF FF) = 4294967295
You can use uint for that - like this:
uint data = uint.Parse("12345678");
byte[] bytes = new[] {
(byte)((data>>24) & 0xFF)
, (byte)((data>>16) & 0xFF)
, (byte)((data>>8) & 0xFF)
, (byte)((data>>0) & 0xFF)
};
Demo.
To convert the string to bytes you can use BitConverter.GetBytes:
var byteArray = BitConverter.GetBytes(Int32.Parse(decString)).Reverse().ToArray();
Use the appropriate type instead of Int32 if the string is not allways an 32 bit integer.
Then you could check the lenght and add padding bytes if needed:
if (byteArray.Length < 5)
{
var newArray = new byte[5];
Array.Copy(byteArray, 0, newArray, 5 - byteArray.Length, byteArray.Length);
byteArray = newArray;
}
You can use Linq:
String source = "12345678";
// "BC614E"
String result = String.Join("", BigInteger
.Parse(source)
.ToByteArray()
.Reverse()
.SkipWhile(item => item == 0)
.Select(item => item.ToString("X2")));
In case you want Byte[] it'll be
// [0xBC, 0x61, 0x4E]
Byte[] result = BigInteger
.Parse(source)
.ToByteArray()
.Reverse()
.SkipWhile(item => item == 0)
.ToArray();

Categories