奇怪的SNMP转换操作

以下内容来自Richard Blum的C#Network Programmingm:

public byte[] get(string request, string host, string community, string_ mibstring) { byte[] packet = new byte[1024]; byte[] mib = new byte[1024]; int snmplen; int comlen = community.Length; string[] mibvals = mibstring.Split('.'); int miblen = mibvals.Length; int cnt = 0, temp, i; int orgmiblen = miblen; int pos = 0; // Convert the string MIB into a byte array of integer values // Unfortunately, values over 128 require multiple bytes // which also increases the MIB length for (i = 0; i  127) { mib[cnt] = Convert.ToByte(128 + (temp / 128)); mib[cnt + 1] = Convert.ToByte(temp - ((temp / 128) * 128)); cnt += 2; miblen++; } else { mib[cnt] = Convert.ToByte(temp); cnt++; } } snmplen = 29 + comlen + miblen - 1; //Length of entire SNMP packet //The SNMP sequence start packet[pos++] = 0x30; //Sequence start packet[pos++] = Convert.ToByte(snmplen - 2); //sequence size //SNMP version packet[pos++] = 0x02; //Integer type packet[pos++] = 0x01; //length packet[pos++] = 0x00; //SNMP version 1 //Community name packet[pos++] = 0x04; // String type packet[pos++] = Convert.ToByte(comlen); //length //Convert community name to byte array byte[] data = Encoding.ASCII.GetBytes(community); for (i = 0; i < data.Length; i++) { packet[pos++] = data[i]; } } 

我不明白以下代码:

  for (i = 0; i  127) { mib[cnt] = Convert.ToByte(128 + (temp / 128)); mib[cnt + 1] = Convert.ToByte(temp - ((temp / 128) * 128)); cnt += 2; miblen++; } else { mib[cnt] = Convert.ToByte(temp); cnt++; } } 

我知道如果temp大于一个字节,这就是放入两个字节。 但是计算结果是128+(temp / 128)然后是第二个字节:temp-(temp / 128)* 128,这是我不明白的。

请帮忙,谢谢。

以下是从了解SNMP MIB页面394引用的,因为本书比其他任何人更好地描述了技术细节,

编码的OBJECT IDENTIFIER由编码和连接的原始值中的每个子标识符组成。 每个子标识符被编码为一系列八位字节,如下所示,

  • 每个八位位组中的位8通过将该位设置为0来指示它是否是子标识符的最后一个八位位组
  • 当连接时,八位字节中的第7位到第1位形成子标识符的值
  • 子标识符中的第一个八位字节可能不具有值80(在HEX中)。 这确保了最小数量的八位字节用于编码。 值80(以hex表示)表示跟随更多八位字节,但值比特(7-1)设置为零。

问题体中的粘贴源代码实际上遵循解析字节的规则。 因此,如果您了解规则,则可以理解代码。

(更新:规则来自ITU-T X.690,ISO / IEC 8825-1 。)

如果temp大于127,那么它将被分割为2个字节。 让我们来看看2个例子/

 temp = 100; 128 + (temp / 128); //(temp / 128) = 0 + 128 so the mib[cnt] is set to 128 temp - ((temp/128) * 128); // 0*128 = 0. subtracted from temp leaves the original. so you end up with mib[cnt] = 128; mib[cnt+1] = 100; 

现在,如果temp> 127

 temp = 200; 128 + (temp / 128); //(temp / 128) = 1 + 128 so the mib[cnt] is set to 129 temp - ((temp/128) * 128); // 1*128 = 128. 200-128 = 72. so you end up with mib[cnt] = 129; mib[cnt+1] = 72; 

所以基本上,它是一个数字,测试它是否> 7个字节(-128 => +127是一个有符号字节),如果你提供的数字将溢出该范围,它将它转换为2字节值/

这适用于所有值:

  for (i = 0; i < orgmiblen; i++) { temp = Convert.ToInt64(mibvals[i]); int k = (int)Math.Log((Double)temp, (Double)2) / 7; miblen += k; int continuation = 0; do { mib[cnt++ + k] = Convert.ToByte((temp & 127) + continuation); temp = ((int)(temp / 128)); continuation = 128; k -= 2; } while (temp > 0); }