Así que estoy tratando de leer en un archivo con algunas cadenas binarias, es decir: 10000010 00000000 0000 **** ********. El script convertirá los * 's en 0 y 1, por lo que habrá dos cadenas binarias que se verán así:

10000010 00000000 00000000 00000000 y 10000010 00000000 00001111 11111111.

Luego, el script los convertirá a direcciones IP, por lo que en este ejemplo, mi script debería devolver 130.0.0.0 y 130.0.15.255

Este es mi código hasta ahora:

def main():
    text=open('filename', 'r').readlines()
    for line in text:
        words = line.split(" ")
        words_2=list(words)
        for char in words:
            low_range=char.replace('*','0')
            conversion=str(int(low_range, 2))
            decimal='.'.join(map(str,conversion))
            print(decimal)
        for char in words_2:
            high_range=char.replace('*','1')
            conversion_2=str(int(high_range, 2))
            decimal='.'.join(map(str,conversion_2))
            print(decimal)
main()

Cuando ejecuto mi código, se imprime:

1.3.0  
0  
0  
0  
1.3.0  
0  
6.3  
2.5.5  
1.3.0  
0  
6.4  
0  
1.3.0  
0  
9.5  
2.5.5  
1.3.0  
0  
1.2.8  
0  
1.3.0  
0  
1.9.1  
2.5.5  
1.3.0  
0  
1.3.0  
0  
1.9.2  
0  
1.3.0  
0  
2.5.5  
2.5.5 

Cuando realmente quiero que se imprima:

130.0.0.0  
130.0.63.255  
130.0.64.0  
130.0.95.255  
130.0.128.0  
130.0.191.255  
130.0.192.0  
130.0.255.255  

¿Alguien puede ayudar a explicar lo que estoy haciendo mal?

0
ojbomb227 13 may. 2016 a las 03:38

3 respuestas

La mejor respuesta

Usted está uniendo las letras de la representación decimal del byte, mientras que debe unir los bytes mismos.

decimal='.'.join(map(str,conversion))

También imprime cada byte de una ip en su propia línea

print(decimal)

Así es como escribiría el bucle:

for line in text:
    words = line.split(" ")

    for bit in '01':        
        ip = []
        for word in words:
            byte=word.replace('*', bit)
            ip.append(str(int(byte, 2)))
        print '.'.join(ip)
0
robyschek 13 may. 2016 a las 01:10

Puede usar un formato simple:

"%d.%d.%d.%d" % (0b10000010, 0b00000000, 0b00000000, 0b00000000)
# '130.0.0.0'

Para leer un número binario de una cadena (digamos "10000010") use:

int("10000010", 2)
# 130

Si desea trabajar con direcciones IP, sugiero usar ipaddress:

>>> import ipaddress
>>> ipaddress.IPv4Address("%d.%d.%d.%d" % (0b10000010, 0b00000000, 0b00000000, 0b00000000))
IPv4Address('130.0.0.0')

Sin embargo, no está disponible en Python 2.x

0
Reut Sharabani 13 may. 2016 a las 00:58

Su ejemplo divide la entrada por espacios en blanco en la variable words. Luego itera sobre las palabras, las convierte a int y de nuevo a cadena a la variable conversion. Todo eso tiene sentido.

El problema está en la siguiente línea:

decimal='.'.join(map(str,conversion))

Cuando se ejecuta por primera vez, el valor es '130'. La llamada map es innecesaria, solo convierte la conversion en una lista de cadenas: ['1', '3', '0']. Luego, une las cadenas junto con . para obtener 1.3.0 que vio en la salida. Tenga en cuenta que obtendría el mismo resultado incluso si eliminara map desde entonces join simplemente iteraría sobre los caracteres en la cadena.

En lugar de iterar sobre los caracteres, simplemente convierta cada palabra con int tal como lo está haciendo y recójalas en una lista. Luego conviértalos a cadenas con map o lista de comprensión y finalmente únalas con ..

Aquí hay un breve ejemplo que lo hace:

with open('test.txt') as text:
    for line in text:
        print '.'.join(str(int(x, 2)) for x in line.split())
0
niemmi 13 may. 2016 a las 01:03