转换php中python代码以计算SNMP VLAN掩码的位掩码的最佳方法


Best method to convert the python code in php for bitmask calculation for SNMP VLAN masks

我有一些python代码,我想在100%php代码中使用这些代码。你知道我如何转换代码吗???我在转换代码时遇到了问题,尤其是get位和set位部分。

通过snmp从交换机中读取位掩码,掩码表示交换机端口在定义的vlan中。示例:

snmpget 1.3.6.1.2.1.17.7.1.4.3.1.2。返回类似F100000000000000的十六进制字符串

每个十六进制数字表示交换机的4个物理LAN端口。这个例子中的第一个数字是F,它的意思是二进制1111。这意味着1-4的每个端口都在vlan中。

如果你只想要端口1、2和4,掩码将是1101,并且是十六进制D。

该代码的目标是,例如,我想知道端口15是否在vlan中(getbitatposition),如果不是,我可以更改端口位置的位掩码(setbitatpositive)。

例如,端口15位于从左起的字符4中:

F=端口1-4

1=端口5-8

0=端口9-12

0=端口13-16=>HEX 0=>二进制0000

要获得vlan中的端口15,我必须将第3位从0000更改为0010,并将其转换回十六进制=>2。

例如,新掩码将为F102000000000000

python代码:

def convertHexCharacterToInt(char):
    if (char.upper() == "A"):
        return 10
    elif (char.upper() == "B"):
        return 11
    elif (char.upper() == "C"):
        return 12
    elif (char.upper() == "D"):
        return 13
    elif (char.upper() == "E"):
        return 14
    elif (char.upper() == "F"):
        return 15
    else:
        return (int(char))
def convertIntToHexCharacter(integer):
    if (integer < 0 or integer > 15):
        return "-1"
    if (integer < 10):
        return str(integer)
    elif (integer == 10):
        return "A"
    elif (integer == 11):
        return "B"
    elif (integer == 12):
        return "C"
    elif (integer == 13):
        return "D"
    elif (integer == 14):
        return "E"
    elif (integer == 15):
        return "F"   
def __getBitAtPosition(position, bitmap):
    for x in range(0, len(bitmap)):
        mask = 0x8
        for y in range(0, 4):
            if (((x * 4) + y + 1) == position):
                return (convertHexCharacterToInt(bitmap[x]) & mask) != 0
            mask = mask >> 1
    return None
def __setBitAtPosition(position, bitmap, value):
    if (__getBitAtPosition(position, bitmap) == value):
        return bitmap
    charPosition = (position + 3) / 4 - 1
    bitPosition = int(math.fabs((position - (charPosition * 4)) - 4))
    bitValue = 2 ** bitPosition
    fourBitValue = convertHexCharacterToInt(bitmap[charPosition])
    newValue = None
    if (value):
        newValue = fourBitValue + bitValue
    else:
        newValue = fourBitValue - bitValue
    newBitmap = bitmap[:charPosition] + convertIntToHexCharacter(newValue) + bitmap[charPosition + 1:]
    return newBitmap

这是我的第一次尝试,但结果不一样:

private function _convertHexCharacterToInt($char){
    if (strtoupper($char) == "A"){
        return 10;}
    elseif (strtoupper($char) == "B"){
        return 11;}
    elseif (strtoupper($char) == "C"){
        return 12;}
    elseif (strtoupper($char) == "D"){
        return 13;}
    elseif (strtoupper($char) == "E"){
        return 14;}
    elseif(strtoupper($char) == "F"){
        return 15;}
    else {
        return $char;
    }
}
private function _getBitAtPosition($pos,$bitmap){
    foreach(range(0,strlen($bitmap)) as $x){
    $mask=0x8;
    foreach(range(0,3) as $y){
      if((($x * 4) + $y + 1) == $pos){
        if($this->_convertHexCharacterToInt(substr($bitmap,$x,1))&$mask != 0{
          return $this->_convertHexCharacterToInt(substr($bitmap,$x,1))&$mask;
        }
        $mask = $mask >> 1
      }
    }
    }
}

我可以解决第一部分,我认为它有效:

private function _getBitAtPosition($pos,$bitmap){
    for($x=0;$x<strlen($bitmap);$x++){
    $mask=0x8;
    for($y=0;$y<4;$y++){
      if((($x * 4) + $y + 1) == $pos){
        if((hexdec(substr($bitmap,$x,1))&$mask) != 0){
          return True;
        }       
      }
       $mask = $mask >> 1;
    }
    }
}

我还发现第二部分的解决方案可能不是漂亮的代码,而是实用的:

private function _setBitAtPosition($pos,$bitmap,$value){
if($this->_getBitAtPosition($pos,$bitmap) == $value){
    return $bitmap;
}
  $charpos = intval((($pos + 3) / 4 - 1));
  $bitpos = abs(($pos - ($charpos * 4)) - 4);
  $bitvalue = pow(2,$bitpos);
$fourbitvalue=hexdec(substr($bitmap,$charpos,1));
$newvalue = 0;
if($value){
    $newvalue = $fourbitvalue + $bitvalue;
} else {
    $newvalue = $fourbitvalue - $bitvalue;
}
$newbitmap = substr($bitmap,0,$charpos).dechex($newvalue).substr($bitmap,$charpos+1);
return $newbitmap;
}

这是我的perl函数,它给出了一个带有范围的位位置集列表。我正在使用它来解析vlan成员身份位掩码,但这并不重要。例如:

# ./test.pl 6E
1-2,4-6
# ./test.pl FF
0-7
# ./test.pl 7fe7fffffe
1-10,13-38

来源:

sub vlans_list {
  my $raw=shift;
  my $cur_vlan=0;
  my $last_vlan=undef;
  my $seq_start=undef;
  my $list=undef;
  foreach my $octet (split('', $raw)) {
    $octet = hex($octet);
    for(my $i=0; $i < 4; $i++) {
      if($octet & 0x8) {
        if(defined($seq_start) && ($cur_vlan-$last_vlan) == 1) {
          $last_vlan=$cur_vlan;
        } elsif(!defined($seq_start)) {
          $seq_start=$cur_vlan;
          $last_vlan=$cur_vlan;
        } else {
          print("ERROR: vlans_list: sequencing error'n");
        };
      } else {
        if(defined($seq_start)) {
          if(defined($list)) {
            $list .= ",$seq_start";
          } else {
            $list = "$seq_start";
          };
          if($seq_start != $last_vlan) {
            $list .= "-$last_vlan";
          };
          $seq_start=undef;
          $last_vlan=undef;
        };
      };
      $cur_vlan++;
      $octet= $octet << 1;
    };
  };
  if(defined($seq_start)) {
    if(defined($list)) {
      $list .= ",$seq_start";
    } else {
      $list = "$seq_start";
    };
    if($seq_start != $last_vlan) {
      $list .= "-$last_vlan";
    };
  };
  if(!defined($list)) {
    $list="";
  };
  return $list;
};