【问题标题】:How to convert decimal to hexadecimal and XOR of the hex string如何将十进制转换为十六进制和十六进制字符串的异或
【发布时间】:2019-07-26 20:38:47
【问题描述】:

我有一个字符串数组 (string[]) 作为十进制数,如 0, 0, 4, 142,我想做的是将该数组转换为十六进制数,如 0, 0, 4, 8e 并在 C# 中执行 XOR,但我我没有得到预期的 XOR

代码:

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");
}

【问题讨论】:

  • 如果初始数字是十进制,则不应将其解析为十六进制。
  • 但是它给了我错误的 Xor!
  • 您不应该将数字(例如 142)视为 十六进制Convert.ToInt64(x) 而不是 Convert.ToInt64(x, 16)(在您当前的代码中 Convert.ToInt64("142", 16) 返回 322 而您结果错误)。

标签: c# string xor


【解决方案1】:

由于142 是一个十进制(不是十六进制)数字(你不对待0x142 == 332),将16 放入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
 }

因此您将拥有0 ^ 0 ^ 4 ^ 142 == 138 == 0x8A

编辑:使用格式时,让计算机解释发生了什么:

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));

结果:

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

所以我们有9F。如果您确定正确答案是B1,您应该检查您的数据或/和公式

编辑 2: 如果初始 string 看起来像(参见 cmets)

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

我们可以将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));

结果:

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

【讨论】:

  • 十进制值:0,0,4,20,15,142,0,8,179,141,0, 8, 181, 141, 0,8 期待 b1 但返回 9F
  • 你为什么期待 B1?当我在计算器中对所有这些值进行异或运算时,我得到 9F。
  • @tkausl 所以我想将这些值转换为十六进制,例如:142 is 8e
  • @PrashantPimpale 重要的是要意识到十六进制仍然是整数/数字。它只是一种不同的格式。它们代表相同的东西。
  • 是的,存储的数据之间没有区别,只是呈现给查看者的方式不同。 10 == 0x0A == 二进制 1010
【解决方案2】:

Convert.ToInt64(string,int) 方法指定字符串输入的基础。您正在将“142”转换为 0x142,而不是 0x8e。

只需使用Convert.ToInt64(string)

至于您可能遇到的 XOR 问题,请参阅此帖子:xor with 3 values

根据您提供的数据以及您正在计算校验和的想法,我怀疑您实际需要做的是提供纵向冗余检查。最简单的方法是:

(SumOfAllData & 0xFF) ^ 0xFF + 1

将一个数中的所有位翻转并加 1 的行为也称为二进制补码。

示例代码:

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

【讨论】:

  • @PrashantPimpale 我发布了一个示例。请注意,这仅使用低 8 位。
  • 感谢会调查这个。如果我想将小数点 142 转换回 0x8E 并作为字节传递?
猜你喜欢
  • 1970-01-01
  • 2019-07-27
  • 2018-01-22
  • 1970-01-01
  • 2018-01-31
  • 2017-08-23
  • 2014-03-19
  • 2013-02-07
相关资源
最近更新 更多