So I'm trying to read in a file with some binary strings, i.e:
10000010 00000000 0000**** ********. The script will convert the *'s to both 0 and 1, so there will be two binary strings that look like this:
10000010 00000000 00000000 00000000 and 10000010 00000000 00001111 11111111.
Then the script will convert them to ip addresses, so in this example, my script should return 130.0.0.0 and 130.0.15.255
This is my code so far:
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()
When I run my code, it prints out:
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
When I really want it to print out:
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
Can anyone help explain what I am doing wrong?
You are joining the letters of byte's decimal representation, while you should join the bytes themselves.
decimal='.'.join(map(str,conversion))
Also you print each byte of an ip on its own line
print(decimal)
Here's how I'd write the loop:
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)
You can use simple formatting:
"%d.%d.%d.%d" % (0b10000010, 0b00000000, 0b00000000, 0b00000000)
# '130.0.0.0'
To read a binary number from a string (say "10000010"
) use:
int("10000010", 2)
# 130
If you want to work with ip addresses I suggest using ipaddress
:
>>> import ipaddress
>>> ipaddress.IPv4Address("%d.%d.%d.%d" % (0b10000010, 0b00000000, 0b00000000, 0b00000000))
IPv4Address('130.0.0.0')
However, it's not available under python 2.x
Your example splits the input by whitespace to variable words
. Then you iterate over the words, convert them to int and back to string to variable conversion
. That all makes sense.
The problem is on following line:
decimal='.'.join(map(str,conversion))
When it get's executed for the first time the value is '130'
. The map
call is unnecessary, it just turns the conversion
to list of strings: ['1', '3', '0']
. Then you join the strings together with .
so you get 1.3.0
that you seen in the output. Note that you'd get the same result even if you'd remove map
since then join
would just iterate over characters in the string.
Instead of iterating over the characters just convert every word with int
just like you're doing and collect them to a list. Then convert them to strings with either map
or list comprehension and finally join them together with .
.
Here's a short example that does it:
with open('test.txt') as text:
for line in text:
print '.'.join(str(int(x, 2)) for x in line.split())