Prashant Pimpale
Prashant Pimpale

Reputation: 10697

How to convert decimal to hexadecimal and XOR of the hex string

I have an array of string (string[]) as a decimal number like 0, 0, 4, 142, what I want to do is to convert that array to hexadecimal numbers like 0, 0, 4, 8e and perform an XOR in the C#, but I am not getting expected XOR,

Code:

public CheckSumHelper(string[] array)
{
  this._array = array.Select(x => Convert.ToInt64(x, 16)).ToArray();
}

public string GetCheckSum()
{
   long xor = this._array.Aggregate((x, y) => x ^ y);
   return xor.ToString("X");
}

Upvotes: 1

Views: 736

Answers (2)

Chris
Chris

Reputation: 743

The Convert.ToInt64(string,int) method specifies the base of your string input. You're converting "142" to 0x142, not 0x8e.

Just use Convert.ToInt64(string).

As far as the XOR issue you may be having, see this post: xor with 3 values

Based on the data you've provided and the idea that you're calculating a checksum I suspect that what you actually need to do is provide a Longitudinal Redundancy Check. The easiest way to do this is:

(SumOfAllData & 0xFF) ^ 0xFF + 1

The act of flipping all the bits in a number and adding 1 is also known as the two's compliment.

Example Code:

private int CalcChecksum(int[] array)
{
    int Sum = array.Aggregate(0, (total, value) => total += value);
    return ((Sum & 0xFF) ^ 0xFF) + 1;
}

Upvotes: 1

Dmitrii Bychenko
Dmitrii Bychenko

Reputation: 186668

Since 142 is a decimal (not hexadecimal) number (you don't treat 0x142 == 332), drop 16 in Convert.ToInt64(...):

 public static string GetCheckSum(string[] array) {
   // TODO: validate array here (it must be not null, not empty etc.)

   return array
     .Select(item => Convert.ToInt64(item)) // initial number is decimal           
     .Aggregate((s, item) => s ^ item) 
     .ToString("X");                        // we want final result being hexadecimal
 }

And so you'll have 0 ^ 0 ^ 4 ^ 142 == 138 == 0x8A.

Edit: When working with formats let computer explain what's going on:

private static string GetCheckSumExplained(string test) {
  string[] array = test.Split(',');

  // Routine under test - GetCheckSum 
  string result = GetCheckSum(array);
  // Convert string back to long in order to represent it as binary and decimal
  long resultAsInt = Convert.ToInt64(result, 16);

  string args = string.Join(Environment.NewLine, array
    .Select(item => Convert.ToInt64(item))
    .Select(item => $"{Convert.ToString(item, 2).PadLeft(8, '0')} : {item,3} : 0x{item.ToString("X2")}"));

  return string.Join(Environment.NewLine, 
     args,
    "---------------------",
   $"{Convert.ToString(resultAsInt, 2).PadLeft(8, '0')} : {resultAsInt,3} : 0x{result.PadLeft(2, '0')}");
}

...

string test = "0,0,4,20,15,142,0,8,179,141,0, 8, 181, 141, 0,8"; 

Console.Write(GetCheckSumExplained(test));

Outcome:

00000000 :   0 : 0x00
00000000 :   0 : 0x00
00000100 :   4 : 0x04
00010100 :  20 : 0x14
00001111 :  15 : 0x0F
10001110 : 142 : 0x8E
00000000 :   0 : 0x00
00001000 :   8 : 0x08
10110011 : 179 : 0xB3
10001101 : 141 : 0x8D
00000000 :   0 : 0x00
00001000 :   8 : 0x08
10110101 : 181 : 0xB5
10001101 : 141 : 0x8D
00000000 :   0 : 0x00
00001000 :   8 : 0x08
---------------------
10011111 : 159 : 0x9F

So we have 9F. If you are sure that the right answer is B1 you should examine your data or/and formula

Edit 2: If initial string looks like (see comments)

 00$00$04$20$15$8e$00$08$b3$8d$00$08$b5$8d$00$08

we can implement GetCheckSum as

 // Now we're working with item_1$Item_2$...$Item_N
 public static string GetCheckSum(string value) {
   // TODO: Validate string here

   return value
     .Split('$')
     .Select(item => Convert.ToInt64(item, 16)) // 16 is required in this format
     .Aggregate((s, item) => s ^ item)
     .ToString("X");
 }

 ...

 string test = "00$00$04$20$15$8e$00$08$b3$8d$00$08$b5$8d$00$08";

 // Let's have a look on the the array
 Console.WriteLine(string.Join(", ", test
                   .Split('$')
                   .Select(item => Convert.ToInt64(item, 16))));

 Console.Wrire(GetCheckSum(test));

Outcome:

 0, 0, 4, 32, 21, 142, 0, 8, 179, 141, 0, 8, 181, 141, 0, 8
 B1  

Upvotes: 1

Related Questions