Лучший способ конвертировать код Python в php для вычисления битовой маски для масок SNMP VLAN

У меня есть некоторый код Python, который я хочу использовать в коде PHP на 100%. у вас есть идеи, как я могу конвертировать код ??? У меня есть проблемы с преобразованием кода, особенно часть получить бит и установить бит.

Битовая маска считывается с коммутатора через snmp, и маска представляет порты ведьмы в определенном vlan. Пример:

snmpget 1.3.6.1.2.1.17.7.1.4.3.1.2. возвращает строку HEX, например, F100000000000000

Каждая шестнадцатеричная цифра представляет 4 физически LAN-порта коммутатора. Первая цифра в этом примере — F, что означает двоичный код 1111. Это означает, что каждый порт из 1-4 находится в vlan.

Если вы хотите только порты 1,2 и 4, маска будет 1101 и находится в шестнадцатеричном формате D.

Цель кода заключается в том, что я хочу знать, например, находится ли порт 15 в vlan или нет (getbitatposition), и если нет, то я могу изменить битовую маску в позиции порта (setbitatposition).

Порт 15, например, находится в символе 4 слева:

F = порт 1-4

1 = порт 5-8

0 = порт 9-12

0 = порт 13-16 => HEX 0 => двоичный 0000

Чтобы получить порт 15 в vlan, я должен изменить 3-й бит с 0000 на 0010 и преобразовать его обратно в hex => 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

}
}

}

}

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

}

}
0

Другие решения

Я также нашел, что решение для второй части может быть не хорошим кодом, а функциональным:

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;
}
0

Вот моя функция perl, которая дает список позиций битов, заданных диапазонами. Я использую его для разбора членства в битовой маске, но это не имеет значения.
Например:

# ./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;

};
0
По вопросам рекламы [email protected]