【问题标题】:c# Binary operation on hex valuesc# 对十六进制值进行二元运算
【发布时间】:2013-06-26 10:37:24
【问题描述】:

我有一个十六进制值,例如以下八位位组:82 A9 43

我需要删除所有的 8 位并将它们连接在一起。

例如:如果我们将每个更改为二进制:

82 = 10000010
A9 = 10101001
43 = 01000011

现在我需要使用以下代码删除以上所有内容的 MSB:

                    int t = 0x7F;
                    int hv1 = 0x82;
                    int hv2 = 0xA9;
                    int hv3 = 0x43;

                    int r1 = hv1 & t;
                    int r2 = hv2 & t;
                    int r3 = hv3 & t;

经过上述过程后如下图:

r1 = 10
r2 = 101001
r3 = 100011

但我需要如下:

r1 = 0000010
r2 = 0101001
r3 = 0100011

原因是后来我想连接所有的 r1 | r2 | r3 如下:

000001001010010100011

然后应该将上面的内容转换为整数。

您是否有线索,如何做到这一点。感谢您的帮助。

【问题讨论】:

  • 您是如何获得这些值的?你在申请 ToString() 吗?
  • 我从 UDP 流中获取的原始值。即:82 A9 43
  • 我的意思是你如何获得二进制值?例如,如何将r1 转换为10
  • 从 UDP 流中读取时在 SNMP 中:第 8 个 MSB 位是切换位,需要剥离,然后剩余的 7 位应与下一个字节连接。但是我在这里使用的八位字节值是示例(82 A9 43),它们在实际场景中可能会有所不同。但我的目标是一样的。取 OID 字节检查第 8 位是否为 1,如果是,则将其剥离为 7 位并连接到下一个八位字节(下一个八位字节将具有相同的 7 位,并去掉第 8 位)
  • @musefan:我正在使用 0x7F 删除第 8 位,但这样做 C# 也会删除前导零,这是我不想要的,我想为每个八位字节保留 7 位

标签: c# binary hex


【解决方案1】:

二进制值的前导 0 并没有真正做任何事情,因此您可以只计算字符并将 0 添加到它们的前面,然后将它们连接在一起

string PadLeft (string s) {
   return string.Format("({0,8})", s)
}

【讨论】:

  • 这里的想法是这些值来自 udp 流作为十六进制字符串,我想通过删除最高有效位(向左)来处理它们,因此所有八位字节都有七位,然后我需要连接这 7 位并得到一个整数结果,如上面的问题所示
  • @user726720 我明白你在说什么,但前导零在数字中很重要。 00001 == 1。即使您转换为字符串并填充字符串,然后再转换回整数,C# 也会去掉前导零。
  • 所以你想构建一个 21 位整数?如果你稍微解释一下目的,人们可能会给出更好的建议。下面的用户 Jonesy 给出了一个很好的填充零的方法
  • 这就是我需要的。我需要保留前导零并将它们作为每个八位字节的 7 位,然后将它们连接起来以获得整数值
  • @HunterMcMillen 但我猜如果你用 0 填充数字然后连接起来,他的要求会给出不同的结果。我猜他可以用 0 作为字符串填充,连接为字符串,然后转换回 int。它仍然会去除前导 0,但会给出他正在寻找的结果
【解决方案2】:

无需先转换为字符串再转换为整数,只需像这样进行整数数学运算:

int concat = r1 << 16 | r2 << 8 | r3;

或更简单地说:

int ttt = 0x7f7f7f; 
int concat = (hv1 << 16 | hv2 << 8 | hv3 & ttt;

【讨论】:

    【解决方案3】:

    在数字上,前导零是无关紧要的。让您的函数返回数字的字符串表示形式,以便您可以将其填充为 8 个字符。

    【讨论】:

      【解决方案4】:

      如果你想要它们,就像你描述的那样,只需在前面加上一些零,它不会改变二进制值

      private static string AddZeros(string r)
          {
              while (r.Length < 8)
                  r = "0" + r;
      
              return r;
          }
      

      【讨论】:

        【解决方案5】:

        目前尚不清楚您如何将整数值转换为二进制字符串,但我想您正在做这样的事情:

        string binaryR1 = Convert.ToString(r1, 2);//binaryR1 = "10"
        

        然后您可以使用PadLeft() 函数填充字符串:

        binaryR1 = binaryR1.PadLeft(7, '0');//binaryR1 = "0000010"
        

        或单行:

        string binaryR1 = Convert.ToString(r1, 2).PadLeft(7, '0');//binaryR1 = "0000010"
        

        注意:这些值已填充为 7 位,因为您不需要 MSB

        将其应用于所有 3 个值将允许您连接到完整的字符串:

        string full = binaryR1 + binaryR2 + binaryR3;//full = "000001001010010100011"
        

        【讨论】:

          【解决方案6】:

          试试这样的:

          int r1 = hv1 & 0x7F;
          int r2 = hv2 & 0x7F;
          int r3 = hv3 & 0x7F;
          int res = ( r1 << 14 ) | ( r2 << 7 ) | r3;
          

          这应该去掉每个字节的第 8 位,然后将每个字节的第 0-7 位连接成一个 21 位数字:

          111111122222223333333 // where 1 are bits from r1, 2 from r2 and so on
          

          这是你想要的吗?

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2014-10-30
            • 1970-01-01
            • 2012-05-18
            • 2012-09-12
            • 2015-03-30
            • 2014-11-30
            • 1970-01-01
            • 2019-07-29
            相关资源
            最近更新 更多