【问题标题】:0 is converted to 1280 转换为 128
【发布时间】:2017-09-18 12:11:08
【问题描述】:

我正在尝试从主机 Linux 到目标系统进行 SNMP 设置。但是,设置的不是正确的值,而是错误的值。经过一番研究,我做了这张表:

Linux snmp 中十进制值的十六进制表示

0 - 0x80 - 1000 0000 - 0 is converted to 128
1 - 0x40 - 0100 0000 - 1 is converted to 64
2   0x20 - 0010 0000 - 2 is converted to 32
3   0x10 - 0001 0000 - 3 is converted to 16
4   0x08 - 0000 1000 - 4 is converted to 8
5   0x04 - 0000 0100 - 5 is converted to 4
6   0x02 - 0000 0010 - 6 is converted to 2
7   0x01 - 0000 0001 - is converted to 1

目标系统中十进制值的十六进制表示

0 - 0x00 - 0000 0000
1 - 0x01 - 0000 0001
2   0x02 - 0000 0010
3   0x03 - 0000 0011
4   0x04 - 0000 0100
5   0x05 - 0000 0101
6   0x06 - 0000 0110
7   0x07 - 0000 0111

我有两个问题:

  1. 此问题背后的原因可能是什么?
  2. 有谁知道如何在 C 程序中将这些 Linux 值转换为正确的目标值?

【问题讨论】:

  • 疯狂猜测:按位反转值并得到“1”位的位置,然后减去 1 => 你会得到你的数字。
  • 对不起,我不知道你在这里问什么。您能否创建一个minimal reproducible example 来说明您的代码在哪里产生了不正确的结果?
  • 你所有的价值观似乎都是正确的。 0x80 128 十进制等。那么什么是“错误”?您希望这些值是多少?
  • 一个 XY 问题...?
  • 你能详细说明一下情况吗?你如何设置这些值?使用 snmpset cli 工具?对象的oid和数据类型是什么?您如何检查设置了哪些值?

标签: c linux snmp data-conversion


【解决方案1】:

如果我正确理解您的问题,您会收到一个字节,该字节使用 one-hot 编码对 8 个值(0 到 7)进行编码。请参阅https://en.wikipedia.org/wiki/One-hot(注意:您的位顺序似乎颠倒了)。

如果您只是将单热编码位模式放入目标系统上的字节变量中,您将不会获得原始值,因为您的目标系统使用另一种编码(可能是 2 的补码) .换句话说 - 给定的位模式在 one-hot 编码和 2 的补码编码中具有不同的含义。

因此,任务是将 one-hot 编码值转换为目标系统上的等效值。

你可以选择一个简单的 switch 语句——比如:

int main(void)
{
  unsigned char linux_snmp_value = 0x20;
  unsigned char target_value = 255;
  switch(linux_snmp_value)
  {
    case 0x80:
        target_value = 0;
        break;
    case 0x40:
        target_value = 1;
        break;
    case 0x20:
        target_value = 2;
        break;

    // Add the remaining cases here

    default:
        // Illegal value
        // Add some error handling
        break;
  }
  printf("Target value %d\n", target_value);
  return 0;
}

如果你更喜欢循环,它可能是这样的:

int main(void)
{
  unsigned char linux_snmp_value = 0x01;
  unsigned char target_value = 0;
  unsigned char mask = 0x80;
  while (mask)
  {
    if (mask == linux_snmp_value) break;
    ++target_value;
    mask = mask >> 1;
  }
  if (mask == 0)
  {
    // Illegal value
    // Add some error handling
    printf("ERROR\n");
    return -1;
  }
  printf("Target value %d\n", target_value);
  return 0;
}

【讨论】:

  • 感谢您的回答。尽管它绝对是完美的解决方案,但恐怕它不适用于我的情况。无论如何,谢谢你的回答。 :)
【解决方案2】:

如果可移植性不是问题(例如你不玩在 VAX 或 AVR8 机器上编译),你可以使用机器指令来解决它

asm (“bsrl %1, %0” : “=r” (position) : “r” (number));

你也可以把它包装成漂亮的内联函数。 ARM、MIPS、PIC 和许多其他设备上都提供了类似的指令。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-09-13
    • 1970-01-01
    • 2017-12-26
    • 2021-12-07
    • 2011-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多