简体   繁体   English

如何将十进制转换为十六进制字符串的十六进制和XOR

[英]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 , 我有一个字符串数组( string[] )作为十进制数字,如0, 0, 4, 142 ,我想要做的就是将数组转换为十六进制数字,如0, 0, 4, 8e并在其中执行XOR C#,但我并没有期望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");
}

The Convert.ToInt64(string,int) method specifies the base of your string input. Convert.ToInt64(string,int)方法指定字符串输入的基数。 You're converting "142" to 0x142, not 0x8e. 您正在将“ 142”转换为0x142,而不是0x8e。

Just use Convert.ToInt64(string) . 只需使用Convert.ToInt64(string)

As far as the XOR issue you may be having, see this post: xor with 3 values 至于您可能遇到的XOR问题,请参阅这篇文章: 具有3个值的xor

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. 翻转数字中的所有位并加1的动作也被称为二的补语。

Example Code: 示例代码:

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

Since 142 is a decimal (not hexadecimal ) number (you don't treat 0x142 == 332 ), drop 16 in Convert.ToInt64(...) : 由于142十进制数 (而不是十六进制数)(您不对待0x142 == 332 ),因此在Convert.ToInt64(...)删除16

 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 . 因此,您将拥有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 . 所以我们有9F If you are sure that the right answer is B1 you should examine your data or/and formula 如果您确定正确的答案是B1 ,则应检查数据或/和公式

Edit 2: If initial string looks like (see comments) 编辑2:如果初始string看起来像(请参阅注释)

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

we can implement GetCheckSum as 我们可以实现GetCheckSum

 // 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  

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM