LongtoIp problem

Discuss using and improving Lua and the Lua Player specific to the PSP.

Moderators: Shine, Insert_witty_name

Post Reply
aserto
Posts: 22
Joined: Mon Apr 17, 2006 10:38 pm

LongtoIp problem

Post by aserto »

Im'm writing an irc client in lua. For the dcc send support i have to convert a long integer ip to an human readable ip. I wrote this function:

Code: Select all

function longtoip(long)
    ip = ""
    for i=3,0,-1 do
        ip = ip .. (long / math.pow(256,i))
        long = long - math.floor((long / math.pow(256,i)))*math.pow(256,i)
        if i>0 then ip = ip .. "." end      
    end
    return ip
end
this function converts a number like this: 4294967295 to 255.255.255.255
i tested it on lua5.1 and works. But in luaplayer doesn't work... I don't know what to do
User avatar
Jim
Posts: 476
Joined: Sat Jul 02, 2005 10:06 pm
Location: Sydney
Contact:

Post by Jim »

I suspect it doesn't work because psp lua uses float instead of double internally.
Can you use 'shift' and 'and' instead?
Pseudo code

ip=""
ip=ip .. addr shr 24
ip=ip .. "."
ip=ip .. (addr shr 16) and 255
ip=ip .. "."
ip=ip .. (addr shr 8) and 255
ip=ip .. "."
ip=ip .. addr and 255

Jim
aserto
Posts: 22
Joined: Mon Apr 17, 2006 10:38 pm

Post by aserto »

Your idea is good... but luaplayer 0.16 doesn't support shift operators.
Shine says that x>>y == math.floor(x / math.pow(2, y)).
http://forums.ps2dev.org/viewtopic.php?t=3138
So the result is the same as my function.
SSpeare
Posts: 63
Joined: Tue May 23, 2006 11:45 pm
Contact:

Post by SSpeare »

What exactly is the output from the function in luaplayer? The problem lies somewhere in the double->float issue or in the math library. Either you are exceeding the precision of floats or you're using a function that doesn't work as expected.

Does math.pow() work in luaplayer?
Does math.floor() work?
If you assign a variable to the MAX_INT number (429...) then you examine the variable does it still contain the same value?
aserto
Posts: 22
Joined: Mon Apr 17, 2006 10:38 pm

Post by aserto »

The function works fine with the first 3 numbers. But the last number is wrong.
SSpeare
Posts: 63
Joined: Tue May 23, 2006 11:45 pm
Contact:

Post by SSpeare »

What exactly does it return for the last number?

Maybe math.pow(256,0) isn't returning 1.
aserto
Posts: 22
Joined: Mon Apr 17, 2006 10:38 pm

Post by aserto »

math.pow(256,0) returns 1
SSpeare
Posts: 63
Joined: Tue May 23, 2006 11:45 pm
Contact:

Post by SSpeare »

I don't think a float has enough precision to hold all the digits in a long. The problem is that there are too many unique digits. I have a version of lua built on the PC that uses floats instead of doubles (you should really make that change to your test lua5.1). This is what I get:

Code: Select all

local f = 4294967295
print("Value is " .. f)
printf("LongToIp is " .. longtoip(f) .."\n")
-- Value is 4294967296
-- LongToIp is 256.0.0.0
You may see different results in luaplayer because the rounding/clamping is probably machine-dependent (FPU-dependent I suppose).

So, your function is probably correct, but the number gets mangled because it can't fit into a float. You're going to need to store the IP differently, maybe actually use four integers instead, or build a nice table/object with some methods.
aserto
Posts: 22
Joined: Mon Apr 17, 2006 10:38 pm

Post by aserto »

can you give me an example?
SSpeare
Posts: 63
Joined: Tue May 23, 2006 11:45 pm
Contact:

Post by SSpeare »

Something like this maybe. I put this in a file ip.lua and then require("ip")

Code: Select all

--usage:
-- local ip = IP:new(255,255,255,0)
-- print(ip:toString())
-- local ip = IP:new({255,255,255,0})
-- print(ip:toString())

IP = {}
local mt = {}

mt.__index = IP

function IP:new(a,b,c,d)
	local n = {}
	-- if they just pass a table
	if (a and type(a) == "table") then
		for i=1,#s do
			n[i] = s[i]
		end
	else if (a and b and c and d) then
		-- if they pass four integers
		n[1] = a
		n[2] = b
		n[3] = c
		n[4] = d
	end
	return setmetatable(n, mt)
end

function IP:toString()
	return self[1].."."..self[2].."."..self[3].."."..self[4]
end
You can add methods to IP like in the :toString() example. I'm sure it would be possible to parse a long that is stored in lua as a string and turn it into this IP object also.
aserto
Posts: 22
Joined: Mon Apr 17, 2006 10:38 pm

Post by aserto »

Yes.. but the problem is that i'm writing an irc client and when a user sends a file via DCC he sends the following string:

nick!user@host PRIVMSG nick :\001DCC SEND Filename address port\001

so the user that receives the file has to connect to address:port, but address is in the long format.
romero126
Posts: 200
Joined: Sat Dec 24, 2005 2:42 pm

Post by romero126 »

Ive faced a similar problem as well, and the simpilist thing to do is parse the data past where the IRC text goes. so instead of

nick!user@host privmsg nick :blah blah blah

you get "blah blah balh"

Might want to invest in creating a token reader.

In c++ I have one you can probably rip.

However I would use the parser that is already included in the LUA library. Useing Regular Expressions.
aserto
Posts: 22
Joined: Mon Apr 17, 2006 10:38 pm

Post by aserto »

you don't understand the problem. is converting a long int ip to an human readable ip.
romero126
Posts: 200
Joined: Sat Dec 24, 2005 2:42 pm

Post by romero126 »

then explain what do you mean?



Example from the LUAApp's to disp your IP is

while true do
ipAddress = Wlan.getIPAddress()
if ipAddress then break end
System.sleep(100)
end
graphicsPrintln("the PSP IP address is: " .. ipAddress)
graphicsPrintln("try http:// " .. ipAddress .. " on your computer")
aserto
Posts: 22
Joined: Mon Apr 17, 2006 10:38 pm

Post by aserto »

Ok... The long formatted ip is obtained from normal ip using this code:

Code: Select all

tonumber(ip[4])+256*tonumber(ip[3])+256*256*tonumber(ip[2])+256*256*256*tonumber(ip[1])
where ip is a tab:

Code: Select all

ip={"AAA","BBB","CCC","DDD"}
i have to convert the long formatted ip to a normal ip (AAA.BBB.CCC.DDD)
[/code]
Shine
Posts: 728
Joined: Fri Dec 03, 2004 12:10 pm
Location: Germany

Re: LongtoIp problem

Post by Shine »

aserto wrote:this function converts a number like this: 4294967295 to 255.255.255.255
i tested it on lua5.1 and works. But in luaplayer doesn't work... I don't know what to do
In Lua Player 0.20 I've integrated Lua 5.1 with double as number type, to avoid such problems. Now it should work.
aserto
Posts: 22
Joined: Mon Apr 17, 2006 10:38 pm

Post by aserto »

Will Luaplayer 0.20 work on eloader 0.97?
Shine
Posts: 728
Joined: Fri Dec 03, 2004 12:10 pm
Location: Germany

Post by Shine »

aserto wrote:Will Luaplayer 0.20 work on eloader 0.97?
I don't know, because currently I have only a 1.0 and 1.5 PSP, but you can try it, Lua Player 0.20 is released: http://forums.ps2dev.org/viewtopic.php?t=5885
aserto
Posts: 22
Joined: Mon Apr 17, 2006 10:38 pm

Post by aserto »

Doesn't work.... :(
I think I'll write a php script to convert ip. Then I'll put the script on a web hosting. Then the lua program will connect to the web server and will get the converted ip.
I know... It's very lame... But I can't find another solution!
Shine
Posts: 728
Joined: Fri Dec 03, 2004 12:10 pm
Location: Germany

Post by Shine »

aserto wrote:Doesn't work.... :(
Maybe you can write a bit more about what doesn't work. Lua Player 0.20 works? Then this works, too:

Code: Select all

function ip2string(ip)
	local string = nil
	for i = 1, 4 do
		if string then string = string .. "." else string = "" end
		string = string .. ip[i]
	end 
	return string
end

function ip2number(ip)
	local number = 0
	local m = 1
	for i = 1, 4 do
		number = number + ip[i] * m
		m = m * 256
	end
	return number
end

function number2ip(number)
	local ip = {}
	local m = 256
	for i = 1, 4 do
		ip[i] = number % m
		number = math.floor(number / 256)
	end
	setmetatable(ip, { __tostring = ip2string })
	return ip
end

tests = {
	{ { 0, 0, 0, 0 }, 0 },
	{ { 0, 0, 0, 1 }, 16777216 },
	{ { 1, 0, 0, 0 }, 1 },
	{ { 1, 2, 3, 4 }, 67305985 },
	{ { 4, 3, 2, 1 }, 16909060 },
	{ { 212, 227, 39, 202 }, 3391611860 },
	{ { 255, 255, 255, 255 }, 4294967295 } }
y = 0
for _, test in pairs(tests) do
	ip, expected = test[1], test[2]
	number = ip2number(ip)
	assert(number == expected)
	ip2 = number2ip(number)
	assert(ip[1] == ip2[1] and ip[2] == ip2[2] and ip[3] == ip2[3] and ip[4] == ip2[4])
	screen:print(0, y, tostring(ip2), Color.new(255, 255, 255))
	y = y + 10
end
screen.waitVblankStart()
screen.flip()

while true do
	screen.waitVblankStart()
	if Controls.read():start() then break end
end
On my PSP it prints this:
0.0.0.0
0.0.0.1
1.0.0.0
1.2.3.4
4.3.2.1
212.227.39.202
255.255.255.255
aserto
Posts: 22
Joined: Mon Apr 17, 2006 10:38 pm

Post by aserto »

I mean than luaplayer 0.20 doesn't work with eloader 0.97
Shine
Posts: 728
Joined: Fri Dec 03, 2004 12:10 pm
Location: Germany

Post by Shine »

aserto wrote:I mean than luaplayer 0.20 doesn't work with eloader 0.97
Then it would be a good idea to ask the author to enhance eloader 0.97. Maybe the module loading is not supported. A solution might be this thread: http://forums.ps2dev.org/viewtopic.php?t=5663 But I want to concentrate more on Lua Player core development, maybe someone with more knowledge of the PSP module concept can try it.
Post Reply