Dotted IP to Integer

BlitzMax Forums/BlitzMax Programming/Dotted IP to Integer

Czar Flavius(Posted 2010) [#1]
How do I convert a dotted IP TO an Integer?


Jesse(Posted 2010) [#2]
you can store it like you do color 255.255.255.255 = ffffffff


plash(Posted 2010) [#3]
EDIT: HostIP will work only if the hostname/dotted ip is found by the network.


Volker(Posted 2010) [#4]
Inet module


Muttley(Posted 2010) [#5]
What sort of integer? One single int, or 4 (one for each octet)?

SuperStrict

Local ip:String = "192.168.71.23"

Local octets:String[] = ip.Split(".")

' Separate ints for each octet
Local o1:Int = Int(octets[0])
Local o2:Int = Int(octets[1])
Local o3:Int = Int(octets[2])
Local o4:Int = Int(octets[3])

' Encode into a single Int
Local ipInt:Int = 0
For Local octet:String = EachIn octets
	ipInt:Shl 8
	ipInt:+Int(octet)
Next



Czar Flavius(Posted 2010) [#6]
I think this does it
Function ip_to_int(ip_s:String)
	Local s:String[] = (ip_s.split("."))
	Local i:Int[4]
	For Local a = 0 Until 4
		i[a] = Int(s[a])
	Next
	Return (i[0] Shl 24) | (i[1] Shl 16) | (i[2] Shl 8) | (i[3])
End Function



Muttley(Posted 2010) [#7]
You go past the end of your array, try:
Function ip_to_int(ip_s:String)
	Local s:String[] = (ip_s.split("."))
	Local i:Int[4]
	For Local a = 0 Until 3
		i[a] = Int(s[a])
	Next
	Return (i[0] Shl 24) | (i[1] Shl 16) | (i[2] Shl 8) | (i[3])
End Function


Creating an int array is an unecessary step, but if you're not going to be calling it a lot then it won't really matter.

This would probably be quicker:

Function ip_to_int:Int(ip_s:String)
	Local ipInt:Int = 0
	For Local octet:String = EachIn ip_s.Split(".")
		ipInt:Shl 8
		ipInt:+Int(octet)	
	Next
	Return ipInt
End Function


Of course neither have any error checking to make sure the input string is in the correct format. ;)


Jesse(Posted 2010) [#8]
no Muttley, you are wrong


Muttley(Posted 2010) [#9]
@Jesse: In what way?

That test returns -1062713577 which is C0A84717 in hex.

$C0 = 192
$A8 = 168
$47 = 71
$17 = 23

Looks correct to me. ;)


Jesse(Posted 2010) [#10]
he is not getting past the end of the array.


Muttley(Posted 2010) [#11]
@Jesse: Ah, OK. I've never used Until so didn't realise it wasn't just a synonym for "To", which would have definitely been wrong.


Muttley(Posted 2010) [#12]
Just did a little speed test with both approaches

SuperStrict

Const MAX_ADDRESSES:Int = 17850625

Function ip_to_int:Int(ip_s:String)
	Local ipInt:Int = 0
	For Local octet:String = EachIn ip_s.Split(".")
		ipInt:Shl 8
		ipInt:+Int(octet)	
	Next
	Return ipInt
End Function

Function ip_to_int2:Int(ip_s:String)
	Local s:String[] = (ip_s.split("."))
	Local i:Int[4]
	For Local a:Int = 0 Until 4
		i[a] = Int(s[a])
	Next
	Return (i[0] Shl 24) | (i[1] Shl 16) | (i[2] Shl 8) | (i[3])
End Function

Local allIpAddresses:String[] = New String[MAX_ADDRESSES]

Local i:Int = 0
For Local o1:Int = 0 To 64
	For Local o2:Int = 0 To 64
		For Local o3:Int = 0 To 64
			For Local o4:Int = 0 To 64
				allIpAddresses[i] = o1 + "." + o2 + "." + o3 + "." + o4
				i:+1
			Next
		Next
	Next
Next

Print "Number of addresses to convert: " + MAX_ADDRESSES

Local t1:Int

t1 = MilliSecs()
For Local i:Int = 0 To MAX_ADDRESSES - 1
	ip_to_int(allIpAddresses[i])
Next
Print "All addresses converted by ip_to_int in " + (MilliSecs() - t1) + "ms."

t1 = MilliSecs()
For Local i:Int = 0 To MAX_ADDRESSES - 1
	ip_to_int2(allIpAddresses[i])
Next
Print "All addresses converted by ip_to_int2 in " + (MilliSecs() - t1) + "ms."


I generate an array of 17.8 million IP addresses, so it requires about 800MB of memory to run.

The results are as follows:

Debug Mode
----------
Number of addresses to convert: 17850625
All addresses converted by ip_to_int in 20973ms.
All addresses converted by ip_to_int2 in 24272ms.

ip_to_int = 16% Faster


Release Mode
------------
Number of addresses to convert: 17850625
All addresses converted by ip_to_int in 17100ms.
All addresses converted by ip_to_int2 in 20182ms.

ip_to_int = 18% Faster


So, depending on whether it's running in Debug or Release mode, my conversion method is between 16% and 18% faster.

IP Addresses converted per second (ip_to_int): 1043896
IP Addresses converted per second (ip_to_int2): 884482

Of course, unless you have to convert this sort of number of addresses, or otherwise need to use the function in a tight loop, then the difference is probably not worth worrying about. ;)


Czar Flavius(Posted 2010) [#13]
Wow thanks for all that Muttley! However, the only use of the function is to let a player direct connect to an IP address, so probably used about once per program!


Yan(Posted 2010) [#14]
HostIP will work only if the hostname/dotted ip is found by the network.
HostIP() will always* return an integer IP when a, correctly formed, dotted IP is given.


The docs for HostIP() should probably be something like...
Host ip address, or 0 if hostname could not be resolved.



*I know this to be true on Windows and I'd be surprised if it wasn't the same for other OSes.


plash(Posted 2010) [#15]
EDIT: @Yan: Yup, it seems to work this way on Linux too.


Yan(Posted 2010) [#16]
8oO <-- That's my surprised face, that is.

[edit]
Damn you and your swift edits, Sir. ;o)
[/edit]