简体   繁体   中英

Binary to String

I am trying to write an IP address program in Python. However, when I use a mask that's less than 7 to get the network ID, I get strange numbers. For example for IP address 164.36.32.32 and subnet mask 6 I get 43.0.0.0 . Note that netmask contains the whole IP address in binary.

if mask<=8:
 print int(netmask[0:mask],2),".0.0.0"
elif mask>8 and mask<=16:
 print int(netmask[0:8],2),".",int(netmask[8:mask],2)
elif mask>16 and mask<=24:
 print int(netmask[0:8],2),".",int(netmask[8:16],2),".",int(netmask[16:mask],2)
elif mask>24 and mask<=32:
print      int(netmask[0:8],2),".",int(netmask[8:16],2),".",int(netmask[16:24],2),".",int(netmask[24:mask],2),

Python's standard library contains the ipaddress module, which will do most common operations on IP addresses. From your code it seems that your "binary" representation of the IP address is actually a string made up of ones and zeroes. This is not only going to be much less efficient than using integers but also you are going to be using a load more memory than you need. Specifically the information at http://docs.python.org/dev/library/ipaddress#ipaddress.IPv4Interface.network might help. Since this appears to be a learning exercise, though, we might take a look at using your current representation.

I assume you failed to append ".0.0" in the second case and ".0" in the third one.

The best way to perform masking operations, whether using strings or integers, is to deal with the bits first and then translate the bit form into your preferred representation. It is relatively easy to define a function to translate a string of 32 bits into dotted-quad notation. It is also not difficult to build a function to mask an address by retaining only the bits indicated by a network prefix.

address = "11110000110011001010101010100001"
assert len(address) == 32

def dotted_quad(address):
    return ".".join(str(int(address[i*8:(i+1)*8], 2)) for i in range(4))

def net_address(address, prefix):
    return dotted_quad(address[:prefix]+"0"*(32-prefix))

print dotted_quad(address)

for prefix in range(32):
    print net_address(address, prefix)

This prints

240.204.170.161
0.0.0.0
128.0.0.0
192.0.0.0
224.0.0.0
240.0.0.0
240.0.0.0
240.0.0.0
240.0.0.0
240.0.0.0
240.128.0.0
240.192.0.0
240.192.0.0
240.192.0.0
240.200.0.0
240.204.0.0
240.204.0.0
240.204.0.0
240.204.128.0
240.204.128.0
240.204.160.0
240.204.160.0
240.204.168.0
240.204.168.0
240.204.170.0
240.204.170.0
240.204.170.128
240.204.170.128
240.204.170.160
240.204.170.160
240.204.170.160
240.204.170.160
240.204.170.160

which would seem to be doing what you want.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM